From c23f114d3cfbb29b8734b87213d1ec0de404197b Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 27 Apr 2017 11:05:07 +0800 Subject: MdeModulePkg: Move to new location Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.c | 807 ------ .../Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.h | 381 --- .../Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.inf | 62 - .../Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.uni | 21 - .../Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPeiExtra.uni | 21 - MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.c | 455 --- MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.h | 61 - MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c | 2878 ------------------- MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.h | 345 --- MdeModulePkg/Bus/Sd/EmmcDxe/ComponentName.c | 242 -- MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.c | 2016 -------------- MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.h | 503 ---- MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.c | 1198 -------- MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.h | 500 ---- MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf | 67 - MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.uni | 20 - MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxeExtra.uni | 19 - MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.c | 617 ---- MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.h | 377 --- MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.inf | 62 - MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.uni | 21 - .../Bus/Sd/SdBlockIoPei/SdBlockIoPeiExtra.uni | 21 - MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.c | 455 --- MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.h | 61 - MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c | 2941 -------------------- MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.h | 356 --- MdeModulePkg/Bus/Sd/SdDxe/ComponentName.c | 240 -- MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c | 1379 --------- MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.h | 258 -- MdeModulePkg/Bus/Sd/SdDxe/SdDxe.c | 903 ------ MdeModulePkg/Bus/Sd/SdDxe/SdDxe.h | 474 ---- MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf | 66 - MdeModulePkg/Bus/Sd/SdDxe/SdDxe.uni | 20 - MdeModulePkg/Bus/Sd/SdDxe/SdDxeExtra.uni | 20 - 34 files changed, 17867 deletions(-) delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.c delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.h delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.inf delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.uni delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPeiExtra.uni delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.c delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.h delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c delete mode 100644 MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.h delete mode 100644 MdeModulePkg/Bus/Sd/EmmcDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.c delete mode 100644 MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.h delete mode 100644 MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.c delete mode 100644 MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.h delete mode 100644 MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf delete mode 100644 MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.uni delete mode 100644 MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxeExtra.uni delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.c delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.h delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.inf delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.uni delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPeiExtra.uni delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.c delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.h delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c delete mode 100644 MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.h delete mode 100644 MdeModulePkg/Bus/Sd/SdDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c delete mode 100644 MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.h delete mode 100644 MdeModulePkg/Bus/Sd/SdDxe/SdDxe.c delete mode 100644 MdeModulePkg/Bus/Sd/SdDxe/SdDxe.h delete mode 100644 MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf delete mode 100644 MdeModulePkg/Bus/Sd/SdDxe/SdDxe.uni delete mode 100644 MdeModulePkg/Bus/Sd/SdDxe/SdDxeExtra.uni (limited to 'MdeModulePkg/Bus/Sd') diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.c b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.c deleted file mode 100644 index 004670cb28..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.c +++ /dev/null @@ -1,807 +0,0 @@ -/** @file - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EmmcBlockIoPei.h" - -// -// Template for EMMC HC Slot Data. -// -EMMC_PEIM_HC_SLOT gEmmcHcSlotTemplate = { - EMMC_PEIM_SLOT_SIG, // Signature - { // Media - { - MSG_EMMC_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - }, - { - MSG_EMMC_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - }, - { - MSG_EMMC_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - }, - { - MSG_EMMC_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - }, - { - MSG_EMMC_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - }, - { - MSG_EMMC_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - }, - { - MSG_EMMC_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - }, - { - MSG_EMMC_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - } - }, - 0, // MediaNum - { // PartitionType - EmmcPartitionUnknown, - EmmcPartitionUnknown, - EmmcPartitionUnknown, - EmmcPartitionUnknown, - EmmcPartitionUnknown, - EmmcPartitionUnknown, - EmmcPartitionUnknown, - EmmcPartitionUnknown - }, - 0, // EmmcHcBase - { // Capability - 0, - }, - { // Csd - 0, - }, - { // ExtCsd - {0}, - }, - TRUE, // SectorAddressing - NULL // Private -}; - -// -// Template for EMMC HC Private Data. -// -EMMC_PEIM_HC_PRIVATE_DATA gEmmcHcPrivateTemplate = { - EMMC_PEIM_SIG, // Signature - NULL, // Pool - { // BlkIoPpi - EmmcBlockIoPeimGetDeviceNo, - EmmcBlockIoPeimGetMediaInfo, - EmmcBlockIoPeimReadBlocks - }, - { // BlkIo2Ppi - EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION, - EmmcBlockIoPeimGetDeviceNo2, - EmmcBlockIoPeimGetMediaInfo2, - EmmcBlockIoPeimReadBlocks2 - }, - { // BlkIoPpiList - EFI_PEI_PPI_DESCRIPTOR_PPI, - &gEfiPeiVirtualBlockIoPpiGuid, - NULL - }, - { // BlkIo2PpiList - EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, - &gEfiPeiVirtualBlockIo2PpiGuid, - NULL - }, - { // Slot - { - 0, - }, - { - 0, - }, - { - 0, - }, - { - 0, - }, - { - 0, - }, - { - 0, - } - }, - 0, // SlotNum - 0 // TotalBlkIoDevices -}; -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimGetDeviceNo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - OUT UINTN *NumberBlockDevices - ) -{ - EMMC_PEIM_HC_PRIVATE_DATA *Private; - - Private = GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This); - *NumberBlockDevices = Private->TotalBlkIoDevices; - return EFI_SUCCESS; -} - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @par Note: - The MediaInfo structure describes an enumeration of possible block device - types. This enumeration exists because no device paths are actually passed - across interfaces that describe the type or class of hardware that is publishing - the block I/O interface. This enumeration will allow for policy decisions - in the Recovery PEIM, such as "Try to recover from legacy floppy first, - LS-120 second, CD-ROM third." If there are multiple partitions abstracted - by a given device type, they should be reported in ascending order; this - order also applies to nested partitions, such as legacy MBR, where the - outermost partitions would have precedence in the reporting order. The - same logic applies to systems such as IDE that have precedence relationships - like "Master/Slave" or "Primary/Secondary". The master device should be - reported first, the slave second. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimGetMediaInfo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo - ) -{ - EMMC_PEIM_HC_PRIVATE_DATA *Private; - UINT8 SlotNum; - UINT8 MediaNum; - UINT8 Location; - BOOLEAN Found; - - Found = FALSE; - Private = GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This); - - if ((DeviceIndex == 0) || (DeviceIndex > Private->TotalBlkIoDevices)) { - return EFI_INVALID_PARAMETER; - } - - Location = 0; - MediaNum = 0; - for (SlotNum = 0; SlotNum < Private->SlotNum; SlotNum++) { - for (MediaNum = 0; MediaNum < Private->Slot[SlotNum].MediaNum; MediaNum++) { - Location ++; - if (Location == DeviceIndex) { - Found = TRUE; - break; - } - } - if (Found) { - break; - } - } - - MediaInfo->DeviceType = EMMC; - MediaInfo->MediaPresent = TRUE; - MediaInfo->LastBlock = (UINTN)Private->Slot[SlotNum].Media[MediaNum].LastBlock; - MediaInfo->BlockSize = Private->Slot[SlotNum].Media[MediaNum].BlockSize; - - return EFI_SUCCESS; -} - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimReadBlocks ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - UINT32 BlockSize; - UINTN NumberOfBlocks; - EMMC_PEIM_HC_PRIVATE_DATA *Private; - UINT8 SlotNum; - UINT8 MediaNum; - UINT8 Location; - UINT8 PartitionConfig; - UINTN Remaining; - UINT32 MaxBlock; - BOOLEAN Found; - - Status = EFI_SUCCESS; - Found = FALSE; - Private = GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This); - - // - // Check parameters - // - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - if ((DeviceIndex == 0) || (DeviceIndex > Private->TotalBlkIoDevices)) { - return EFI_INVALID_PARAMETER; - } - - Location = 0; - MediaNum = 0; - for (SlotNum = 0; SlotNum < Private->SlotNum; SlotNum++) { - for (MediaNum = 0; MediaNum < Private->Slot[SlotNum].MediaNum; MediaNum++) { - Location ++; - if (Location == DeviceIndex) { - Found = TRUE; - break; - } - } - if (Found) { - break; - } - } - - BlockSize = Private->Slot[SlotNum].Media[MediaNum].BlockSize; - if (BufferSize % BlockSize != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - if (StartLBA > Private->Slot[SlotNum].Media[MediaNum].LastBlock) { - return EFI_INVALID_PARAMETER; - } - - NumberOfBlocks = BufferSize / BlockSize; - - // - // Check if needs to switch partition access. - // - PartitionConfig = Private->Slot[SlotNum].ExtCsd.PartitionConfig; - if ((PartitionConfig & 0x7) != Private->Slot[SlotNum].PartitionType[MediaNum]) { - PartitionConfig &= (UINT8)~0x7; - PartitionConfig |= Private->Slot[SlotNum].PartitionType[MediaNum]; - Status = EmmcPeimSwitch ( - &Private->Slot[SlotNum], - 0x3, - OFFSET_OF (EMMC_EXT_CSD, PartitionConfig), - PartitionConfig, - 0x0 - ); - if (EFI_ERROR (Status)) { - return Status; - } - Private->Slot[SlotNum].ExtCsd.PartitionConfig = PartitionConfig; - } - // - // Start to execute data transfer. The max block number in single cmd is 65535 blocks. - // - Remaining = NumberOfBlocks; - MaxBlock = 0xFFFF; - - while (Remaining > 0) { - if (Remaining <= MaxBlock) { - NumberOfBlocks = Remaining; - } else { - NumberOfBlocks = MaxBlock; - } - - Status = EmmcPeimSetBlkCount (&Private->Slot[SlotNum], (UINT16)NumberOfBlocks); - if (EFI_ERROR (Status)) { - return Status; - } - - BufferSize = NumberOfBlocks * BlockSize; - Status = EmmcPeimRwMultiBlocks (&Private->Slot[SlotNum], StartLBA, BlockSize, Buffer, BufferSize, TRUE); - if (EFI_ERROR (Status)) { - return Status; - } - - StartLBA += NumberOfBlocks; - Buffer = (UINT8*)Buffer + BufferSize; - Remaining -= NumberOfBlocks; - } - return Status; -} - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimGetDeviceNo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - OUT UINTN *NumberBlockDevices - ) -{ - EMMC_PEIM_HC_PRIVATE_DATA *Private; - - Private = GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This); - *NumberBlockDevices = Private->TotalBlkIoDevices; - - return EFI_SUCCESS; -} - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @par Note: - The MediaInfo structure describes an enumeration of possible block device - types. This enumeration exists because no device paths are actually passed - across interfaces that describe the type or class of hardware that is publishing - the block I/O interface. This enumeration will allow for policy decisions - in the Recovery PEIM, such as "Try to recover from legacy floppy first, - LS-120 second, CD-ROM third." If there are multiple partitions abstracted - by a given device type, they should be reported in ascending order; this - order also applies to nested partitions, such as legacy MBR, where the - outermost partitions would have precedence in the reporting order. The - same logic applies to systems such as IDE that have precedence relationships - like "Master/Slave" or "Primary/Secondary". The master device should be - reported first, the slave second. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimGetMediaInfo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo - ) -{ - EFI_STATUS Status; - EMMC_PEIM_HC_PRIVATE_DATA *Private; - EFI_PEI_BLOCK_IO_MEDIA Media; - UINT8 SlotNum; - UINT8 MediaNum; - UINT8 Location; - BOOLEAN Found; - - Found = FALSE; - Private = GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This); - - Status = EmmcBlockIoPeimGetMediaInfo ( - PeiServices, - &Private->BlkIoPpi, - DeviceIndex, - &Media - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Location = 0; - MediaNum = 0; - for (SlotNum = 0; SlotNum < Private->SlotNum; SlotNum++) { - for (MediaNum = 0; MediaNum < Private->Slot[SlotNum].MediaNum; MediaNum++) { - Location ++; - if (Location == DeviceIndex) { - Found = TRUE; - break; - } - } - if (Found) { - break; - } - } - - CopyMem (MediaInfo, &(Private->Slot[SlotNum].Media[MediaNum]), sizeof (EFI_PEI_BLOCK_IO2_MEDIA)); - return EFI_SUCCESS; -} - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimReadBlocks2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - EMMC_PEIM_HC_PRIVATE_DATA *Private; - - Status = EFI_SUCCESS; - Private = GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This); - - Status = EmmcBlockIoPeimReadBlocks ( - PeiServices, - &Private->BlkIoPpi, - DeviceIndex, - StartLBA, - BufferSize, - Buffer - ); - return Status; -} - -/** - The user code starts with this function. - - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCCESS The driver is successfully initialized. - @retval Others Can't initialize the driver. - -**/ -EFI_STATUS -EFIAPI -InitializeEmmcBlockIoPeim ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - EFI_STATUS Status; - EMMC_PEIM_HC_PRIVATE_DATA *Private; - EDKII_SD_MMC_HOST_CONTROLLER_PPI *SdMmcHcPpi; - UINT32 Index; - UINT32 PartitionIndex; - UINTN *MmioBase; - UINT8 BarNum; - UINT8 SlotNum; - UINT8 MediaNum; - UINT8 Controller; - UINT64 Capacity; - EMMC_EXT_CSD *ExtCsd; - EMMC_HC_SLOT_CAP Capability; - EMMC_PEIM_HC_SLOT *Slot; - UINT32 SecCount; - UINT32 GpSizeMult; - - // - // Shadow this PEIM to run from memory - // - if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { - return EFI_SUCCESS; - } - - // - // locate Emmc host controller PPI - // - Status = PeiServicesLocatePpi ( - &gEdkiiPeiSdMmcHostControllerPpiGuid, - 0, - NULL, - (VOID **) &SdMmcHcPpi - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - Controller = 0; - MmioBase = NULL; - while (TRUE) { - Status = SdMmcHcPpi->GetSdMmcHcMmioBar (SdMmcHcPpi, Controller, &MmioBase, &BarNum); - // - // When status is error, meant no controller is found - // - if (EFI_ERROR (Status)) { - break; - } - - if (BarNum == 0) { - Controller++; - continue; - } - - Private = AllocateCopyPool (sizeof (EMMC_PEIM_HC_PRIVATE_DATA), &gEmmcHcPrivateTemplate); - if (Private == NULL) { - Status = EFI_OUT_OF_RESOURCES; - break; - } - Private->BlkIoPpiList.Ppi = (VOID*)&Private->BlkIoPpi; - Private->BlkIo2PpiList.Ppi = (VOID*)&Private->BlkIo2Ppi; - // - // Initialize the memory pool which will be used in all transactions. - // - Status = EmmcPeimInitMemPool (Private); - if (EFI_ERROR (Status)) { - Status = EFI_OUT_OF_RESOURCES; - break; - } - - for (Index = 0; Index < BarNum; Index++) { - Status = EmmcPeimHcGetCapability (MmioBase[Index], &Capability); - if (EFI_ERROR (Status)) { - continue; - } - if (Capability.SlotType != 0x1) { - DEBUG ((EFI_D_INFO, "The slot at 0x%x is not embedded slot type\n", MmioBase[Index])); - Status = EFI_UNSUPPORTED; - continue; - } - - Status = EmmcPeimHcReset (MmioBase[Index]); - if (EFI_ERROR (Status)) { - continue; - } - Status = EmmcPeimHcCardDetect (MmioBase[Index]); - if (EFI_ERROR (Status)) { - continue; - } - Status = EmmcPeimHcInitHost (MmioBase[Index]); - if (EFI_ERROR (Status)) { - continue; - } - - SlotNum = Private->SlotNum; - Slot = &Private->Slot[SlotNum]; - CopyMem (Slot, &gEmmcHcSlotTemplate, sizeof (EMMC_PEIM_HC_SLOT)); - Slot->Private = Private; - Slot->EmmcHcBase = MmioBase[Index]; - CopyMem (&Slot->Capability, &Capability, sizeof (Capability)); - - Status = EmmcPeimIdentification (Slot); - if (EFI_ERROR (Status)) { - continue; - } - - ExtCsd = &Slot->ExtCsd; - if (ExtCsd->ExtCsdRev < 5) { - DEBUG ((EFI_D_ERROR, "The EMMC device version is too low, we don't support!!!\n")); - Status = EFI_UNSUPPORTED; - continue; - } - if ((ExtCsd->PartitioningSupport & BIT0) != BIT0) { - DEBUG ((EFI_D_ERROR, "The EMMC device doesn't support Partition Feature!!!\n")); - Status = EFI_UNSUPPORTED; - continue; - } - - for (PartitionIndex = 0; PartitionIndex < EMMC_PEIM_MAX_PARTITIONS; PartitionIndex++) { - switch (PartitionIndex) { - case EmmcPartitionUserData: - SecCount = *(UINT32*)&ExtCsd->SecCount; - Capacity = MultU64x32 ((UINT64)SecCount, 0x200); - break; - case EmmcPartitionBoot1: - case EmmcPartitionBoot2: - Capacity = ExtCsd->BootSizeMult * SIZE_128KB; - break; - case EmmcPartitionRPMB: - Capacity = ExtCsd->RpmbSizeMult * SIZE_128KB; - break; - case EmmcPartitionGP1: - GpSizeMult = (ExtCsd->GpSizeMult[0] | (ExtCsd->GpSizeMult[1] << 8) | (ExtCsd->GpSizeMult[2] << 16)); - Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB); - break; - case EmmcPartitionGP2: - GpSizeMult = (ExtCsd->GpSizeMult[3] | (ExtCsd->GpSizeMult[4] << 8) | (ExtCsd->GpSizeMult[5] << 16)); - Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB); - break; - case EmmcPartitionGP3: - GpSizeMult = (ExtCsd->GpSizeMult[6] | (ExtCsd->GpSizeMult[7] << 8) | (ExtCsd->GpSizeMult[8] << 16)); - Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB); - break; - case EmmcPartitionGP4: - GpSizeMult = (ExtCsd->GpSizeMult[9] | (ExtCsd->GpSizeMult[10] << 8) | (ExtCsd->GpSizeMult[11] << 16)); - Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB); - break; - default: - ASSERT (FALSE); - continue; - } - - MediaNum = Slot->MediaNum; - if (Capacity != 0) { - Slot->Media[MediaNum].LastBlock = DivU64x32 (Capacity, Slot->Media[MediaNum].BlockSize) - 1; - Slot->PartitionType[MediaNum] = PartitionIndex; - Private->TotalBlkIoDevices++; - Slot->MediaNum++; - } - } - Private->SlotNum++; - } - Controller++; - - if (!EFI_ERROR (Status)) { - PeiServicesInstallPpi (&Private->BlkIoPpiList); - } - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.h b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.h deleted file mode 100644 index 5c8b740e4f..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.h +++ /dev/null @@ -1,381 +0,0 @@ -/** @file - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EMMC_BLOCK_IO_PEI_H_ -#define _EMMC_BLOCK_IO_PEI_H_ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef struct _EMMC_PEIM_HC_PRIVATE_DATA EMMC_PEIM_HC_PRIVATE_DATA; -typedef struct _EMMC_PEIM_HC_SLOT EMMC_PEIM_HC_SLOT; -typedef struct _EMMC_TRB EMMC_TRB; - -#include "EmmcHci.h" -#include "EmmcHcMem.h" - -#define EMMC_PEIM_SIG SIGNATURE_32 ('E', 'M', 'C', 'P') -#define EMMC_PEIM_SLOT_SIG SIGNATURE_32 ('E', 'M', 'C', 'S') - -#define EMMC_PEIM_MAX_SLOTS 6 -#define EMMC_PEIM_MAX_PARTITIONS 8 - -struct _EMMC_PEIM_HC_SLOT { - UINT32 Signature; - EFI_PEI_BLOCK_IO2_MEDIA Media[EMMC_PEIM_MAX_PARTITIONS]; - UINT8 MediaNum; - EMMC_PARTITION_TYPE PartitionType[EMMC_PEIM_MAX_PARTITIONS]; - - UINTN EmmcHcBase; - EMMC_HC_SLOT_CAP Capability; - EMMC_CSD Csd; - EMMC_EXT_CSD ExtCsd; - BOOLEAN SectorAddressing; - EMMC_PEIM_HC_PRIVATE_DATA *Private; -}; - -struct _EMMC_PEIM_HC_PRIVATE_DATA { - UINT32 Signature; - EMMC_PEIM_MEM_POOL *Pool; - EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi; - EFI_PEI_RECOVERY_BLOCK_IO2_PPI BlkIo2Ppi; - EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList; - EFI_PEI_PPI_DESCRIPTOR BlkIo2PpiList; - EMMC_PEIM_HC_SLOT Slot[EMMC_PEIM_MAX_SLOTS]; - UINT8 SlotNum; - UINT8 TotalBlkIoDevices; -}; - -#define EMMC_TIMEOUT MultU64x32((UINT64)(3), 1000000) -#define GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS(a) CR (a, EMMC_PEIM_HC_PRIVATE_DATA, BlkIoPpi, EMMC_PEIM_SIG) -#define GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2(a) CR (a, EMMC_PEIM_HC_PRIVATE_DATA, BlkIo2Ppi, EMMC_PEIM_SIG) - -struct _EMMC_TRB { - EMMC_PEIM_HC_SLOT *Slot; - UINT16 BlockSize; - - EMMC_COMMAND_PACKET *Packet; - VOID *Data; - UINT32 DataLen; - BOOLEAN Read; - EMMC_HC_TRANSFER_MODE Mode; - - UINT64 Timeout; - - EMMC_HC_ADMA_DESC_LINE *AdmaDesc; - UINTN AdmaDescSize; -}; - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimGetDeviceNo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - OUT UINTN *NumberBlockDevices - ); - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @par Note: - The MediaInfo structure describes an enumeration of possible block device - types. This enumeration exists because no device paths are actually passed - across interfaces that describe the type or class of hardware that is publishing - the block I/O interface. This enumeration will allow for policy decisions - in the Recovery PEIM, such as "Try to recover from legacy floppy first, - LS-120 second, CD-ROM third." If there are multiple partitions abstracted - by a given device type, they should be reported in ascending order; this - order also applies to nested partitions, such as legacy MBR, where the - outermost partitions would have precedence in the reporting order. The - same logic applies to systems such as IDE that have precedence relationships - like "Master/Slave" or "Primary/Secondary". The master device should be - reported first, the slave second. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimGetMediaInfo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo - ); - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimReadBlocks ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimGetDeviceNo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - OUT UINTN *NumberBlockDevices - ); - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @par Note: - The MediaInfo structure describes an enumeration of possible block device - types. This enumeration exists because no device paths are actually passed - across interfaces that describe the type or class of hardware that is publishing - the block I/O interface. This enumeration will allow for policy decisions - in the Recovery PEIM, such as "Try to recover from legacy floppy first, - LS-120 second, CD-ROM third." If there are multiple partitions abstracted - by a given device type, they should be reported in ascending order; this - order also applies to nested partitions, such as legacy MBR, where the - outermost partitions would have precedence in the reporting order. The - same logic applies to systems such as IDE that have precedence relationships - like "Master/Slave" or "Primary/Secondary". The master device should be - reported first, the slave second. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimGetMediaInfo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo - ); - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -EmmcBlockIoPeimReadBlocks2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Initialize the memory management pool for the host controller. - - @param Private The Emmc Peim driver private data. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval Others Fail to init the memory pool. - -**/ -EFI_STATUS -EmmcPeimInitMemPool ( - IN EMMC_PEIM_HC_PRIVATE_DATA *Private - ); - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -EmmcPeimAllocateMem ( - IN EMMC_PEIM_MEM_POOL *Pool, - IN UINTN Size - ); - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -EmmcPeimFreeMem ( - IN EMMC_PEIM_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -#endif diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.inf b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.inf deleted file mode 100644 index 4163b528b8..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.inf +++ /dev/null @@ -1,62 +0,0 @@ -## @file -# Description file for the Embedded MMC (eMMC) Peim driver. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = EmmcBlockIoPei - MODULE_UNI_FILE = EmmcBlockIoPei.uni - FILE_GUID = 7F06A90F-AE0D-4887-82C0-FEC7F4F68B29 - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - - ENTRY_POINT = InitializeEmmcBlockIoPeim - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - EmmcBlockIoPei.c - EmmcBlockIoPei.h - EmmcHci.c - EmmcHci.h - EmmcHcMem.c - EmmcHcMem.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - IoLib - TimerLib - BaseMemoryLib - PeimEntryPoint - PeiServicesLib - DebugLib - -[Ppis] - gEfiPeiVirtualBlockIoPpiGuid ## PRODUCES - gEfiPeiVirtualBlockIo2PpiGuid ## PRODUCES - gEdkiiPeiSdMmcHostControllerPpiGuid ## CONSUMES - -[Depex] - gEfiPeiMemoryDiscoveredPpiGuid AND gEdkiiPeiSdMmcHostControllerPpiGuid - -[UserExtensions.TianoCore."ExtraFiles"] - EmmcBlockIoPeiExtra.uni - diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.uni b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.uni deleted file mode 100644 index f90e831019..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.uni +++ /dev/null @@ -1,21 +0,0 @@ -// /** @file -// The EmmcBlockIoPei driver is used to support recovery from EMMC device. -// -// Copyright (c) 2015, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions -// of the BSD License which accompanies this distribution. The -// full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Support recovery from EMMC devices" - -#string STR_MODULE_DESCRIPTION #language en-US "The EmmcBlockIoPei driver is used to support recovery from EMMC device." - diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPeiExtra.uni b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPeiExtra.uni deleted file mode 100644 index 9299c1b5c1..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPeiExtra.uni +++ /dev/null @@ -1,21 +0,0 @@ -// /** @file -// EmmcBlockIoPei Localized Strings and Content -// -// Copyright (c) 2015, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions -// of the BSD License which accompanies this distribution. The -// full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"EMMC BlockIo Peim for Recovery" - - diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.c b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.c deleted file mode 100644 index 0708fab047..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.c +++ /dev/null @@ -1,455 +0,0 @@ -/** @file - -Copyright (c) 2016, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EmmcBlockIoPei.h" - -/** - Allocate a block of memory to be used by the buffer pool. - - @param Pages How many pages to allocate. - - @return The allocated memory block or NULL if failed. - -**/ -EMMC_PEIM_MEM_BLOCK * -EmmcPeimAllocMemBlock ( - IN UINTN Pages - ) -{ - EMMC_PEIM_MEM_BLOCK *Block; - EFI_STATUS Status; - VOID *TempPtr; - EFI_PHYSICAL_ADDRESS Address; - - TempPtr = NULL; - Block = NULL; - - Status = PeiServicesAllocatePool (sizeof(EMMC_PEIM_MEM_BLOCK), &TempPtr); - if (EFI_ERROR (Status)) { - return NULL; - } - - ZeroMem ((VOID*)(UINTN)TempPtr, sizeof(EMMC_PEIM_MEM_BLOCK)); - - // - // each bit in the bit array represents EMMC_PEIM_MEM_UNIT - // bytes of memory in the memory block. - // - ASSERT (EMMC_PEIM_MEM_UNIT * 8 <= EFI_PAGE_SIZE); - - Block = (EMMC_PEIM_MEM_BLOCK*)(UINTN)TempPtr; - Block->BufLen = EFI_PAGES_TO_SIZE (Pages); - Block->BitsLen = Block->BufLen / (EMMC_PEIM_MEM_UNIT * 8); - - Status = PeiServicesAllocatePool (Block->BitsLen, &TempPtr); - if (EFI_ERROR (Status)) { - return NULL; - } - - ZeroMem ((VOID*)(UINTN)TempPtr, Block->BitsLen); - - Block->Bits = (UINT8*)(UINTN)TempPtr; - - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - Pages, - &Address - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - ZeroMem ((VOID*)(UINTN)Address, EFI_PAGES_TO_SIZE (Pages)); - - Block->Buf = (UINT8*)((UINTN)Address); - Block->Next = NULL; - - return Block; -} - -/** - Free the memory block from the memory pool. - - @param Pool The memory pool to free the block from. - @param Block The memory block to free. - -**/ -VOID -EmmcPeimFreeMemBlock ( - IN EMMC_PEIM_MEM_POOL *Pool, - IN EMMC_PEIM_MEM_BLOCK *Block - ) -{ - ASSERT ((Pool != NULL) && (Block != NULL)); -} - -/** - Alloc some memory from the block. - - @param Block The memory block to allocate memory from. - @param Units Number of memory units to allocate. - - @return The pointer to the allocated memory. If couldn't allocate the needed memory, - the return value is NULL. - -**/ -VOID * -EmmcPeimAllocMemFromBlock ( - IN EMMC_PEIM_MEM_BLOCK *Block, - IN UINTN Units - ) -{ - UINTN Byte; - UINT8 Bit; - UINTN StartByte; - UINT8 StartBit; - UINTN Available; - UINTN Count; - - ASSERT ((Block != 0) && (Units != 0)); - - StartByte = 0; - StartBit = 0; - Available = 0; - - for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) { - // - // If current bit is zero, the corresponding memory unit is - // available, otherwise we need to restart our searching. - // Available counts the consective number of zero bit. - // - if (!EMMC_PEIM_MEM_BIT_IS_SET (Block->Bits[Byte], Bit)) { - Available++; - - if (Available >= Units) { - break; - } - - EMMC_PEIM_NEXT_BIT (Byte, Bit); - - } else { - EMMC_PEIM_NEXT_BIT (Byte, Bit); - - Available = 0; - StartByte = Byte; - StartBit = Bit; - } - } - - if (Available < Units) { - return NULL; - } - - // - // Mark the memory as allocated - // - Byte = StartByte; - Bit = StartBit; - - for (Count = 0; Count < Units; Count++) { - ASSERT (!EMMC_PEIM_MEM_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) EMMC_PEIM_MEM_BIT (Bit)); - EMMC_PEIM_NEXT_BIT (Byte, Bit); - } - - return Block->Buf + (StartByte * 8 + StartBit) * EMMC_PEIM_MEM_UNIT; -} - -/** - Insert the memory block to the pool's list of the blocks. - - @param Head The head of the memory pool's block list. - @param Block The memory block to insert. - -**/ -VOID -EmmcPeimInsertMemBlockToPool ( - IN EMMC_PEIM_MEM_BLOCK *Head, - IN EMMC_PEIM_MEM_BLOCK *Block - ) -{ - ASSERT ((Head != NULL) && (Block != NULL)); - Block->Next = Head->Next; - Head->Next = Block; -} - -/** - Is the memory block empty? - - @param Block The memory block to check. - - @retval TRUE The memory block is empty. - @retval FALSE The memory block isn't empty. - -**/ -BOOLEAN -EmmcPeimIsMemBlockEmpty ( - IN EMMC_PEIM_MEM_BLOCK *Block - ) -{ - UINTN Index; - - - for (Index = 0; Index < Block->BitsLen; Index++) { - if (Block->Bits[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - -/** - Unlink the memory block from the pool's list. - - @param Head The block list head of the memory's pool. - @param BlockToUnlink The memory block to unlink. - -**/ -VOID -EmmcPeimUnlinkMemBlock ( - IN EMMC_PEIM_MEM_BLOCK *Head, - IN EMMC_PEIM_MEM_BLOCK *BlockToUnlink - ) -{ - EMMC_PEIM_MEM_BLOCK *Block; - - ASSERT ((Head != NULL) && (BlockToUnlink != NULL)); - - for (Block = Head; Block != NULL; Block = Block->Next) { - if (Block->Next == BlockToUnlink) { - Block->Next = BlockToUnlink->Next; - BlockToUnlink->Next = NULL; - break; - } - } -} - -/** - Initialize the memory management pool for the host controller. - - @param Private The Emmc Peim driver private data. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval Others Fail to init the memory pool. - -**/ -EFI_STATUS -EmmcPeimInitMemPool ( - IN EMMC_PEIM_HC_PRIVATE_DATA *Private - ) -{ - EMMC_PEIM_MEM_POOL *Pool; - EFI_STATUS Status; - VOID *TempPtr; - - TempPtr = NULL; - Pool = NULL; - - Status = PeiServicesAllocatePool (sizeof (EMMC_PEIM_MEM_POOL), &TempPtr); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem ((VOID*)(UINTN)TempPtr, sizeof (EMMC_PEIM_MEM_POOL)); - - Pool = (EMMC_PEIM_MEM_POOL *)((UINTN)TempPtr); - - Pool->Head = EmmcPeimAllocMemBlock (EMMC_PEIM_MEM_DEFAULT_PAGES); - - if (Pool->Head == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Private->Pool = Pool; - return EFI_SUCCESS; -} - -/** - Release the memory management pool. - - @param Pool The memory pool to free. - - @retval EFI_DEVICE_ERROR Fail to free the memory pool. - @retval EFI_SUCCESS The memory pool is freed. - -**/ -EFI_STATUS -EmmcPeimFreeMemPool ( - IN EMMC_PEIM_MEM_POOL *Pool - ) -{ - EMMC_PEIM_MEM_BLOCK *Block; - - ASSERT (Pool->Head != NULL); - - // - // Unlink all the memory blocks from the pool, then free them. - // EmmcPeimUnlinkMemBlock can't be used to unlink and free the - // first block. - // - for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) { - EmmcPeimFreeMemBlock (Pool, Block); - } - - EmmcPeimFreeMemBlock (Pool, Pool->Head); - - return EFI_SUCCESS; -} - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -EmmcPeimAllocateMem ( - IN EMMC_PEIM_MEM_POOL *Pool, - IN UINTN Size - ) -{ - EMMC_PEIM_MEM_BLOCK *Head; - EMMC_PEIM_MEM_BLOCK *Block; - EMMC_PEIM_MEM_BLOCK *NewBlock; - VOID *Mem; - UINTN AllocSize; - UINTN Pages; - - Mem = NULL; - AllocSize = EMMC_PEIM_MEM_ROUND (Size); - Head = Pool->Head; - ASSERT (Head != NULL); - - // - // First check whether current memory blocks can satisfy the allocation. - // - for (Block = Head; Block != NULL; Block = Block->Next) { - Mem = EmmcPeimAllocMemFromBlock (Block, AllocSize / EMMC_PEIM_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - break; - } - } - - if (Mem != NULL) { - return Mem; - } - - // - // Create a new memory block if there is not enough memory - // in the pool. If the allocation size is larger than the - // default page number, just allocate a large enough memory - // block. Otherwise allocate default pages. - // - if (AllocSize > EFI_PAGES_TO_SIZE (EMMC_PEIM_MEM_DEFAULT_PAGES)) { - Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1; - } else { - Pages = EMMC_PEIM_MEM_DEFAULT_PAGES; - } - - NewBlock = EmmcPeimAllocMemBlock (Pages); - if (NewBlock == NULL) { - return NULL; - } - - // - // Add the new memory block to the pool, then allocate memory from it - // - EmmcPeimInsertMemBlockToPool (Head, NewBlock); - Mem = EmmcPeimAllocMemFromBlock (NewBlock, AllocSize / EMMC_PEIM_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - } - - return Mem; -} - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -EmmcPeimFreeMem ( - IN EMMC_PEIM_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - EMMC_PEIM_MEM_BLOCK *Head; - EMMC_PEIM_MEM_BLOCK *Block; - UINT8 *ToFree; - UINTN AllocSize; - UINTN Byte; - UINTN Bit; - UINTN Count; - - Head = Pool->Head; - AllocSize = EMMC_PEIM_MEM_ROUND (Size); - ToFree = (UINT8 *) Mem; - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the memory to free. - // - if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) { - // - // compute the start byte and bit in the bit array - // - Byte = ((ToFree - Block->Buf) / EMMC_PEIM_MEM_UNIT) / 8; - Bit = ((ToFree - Block->Buf) / EMMC_PEIM_MEM_UNIT) % 8; - - // - // reset associated bits in bit array - // - for (Count = 0; Count < (AllocSize / EMMC_PEIM_MEM_UNIT); Count++) { - ASSERT (EMMC_PEIM_MEM_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ EMMC_PEIM_MEM_BIT (Bit)); - EMMC_PEIM_NEXT_BIT (Byte, Bit); - } - - break; - } - } - - // - // If Block == NULL, it means that the current memory isn't - // in the host controller's pool. This is critical because - // the caller has passed in a wrong memory point - // - ASSERT (Block != NULL); - - // - // Release the current memory block if it is empty and not the head - // - if ((Block != Head) && EmmcPeimIsMemBlockEmpty (Block)) { - EmmcPeimFreeMemBlock (Pool, Block); - } - - return ; -} diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.h b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.h deleted file mode 100644 index af0c93c610..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHcMem.h +++ /dev/null @@ -1,61 +0,0 @@ -/** @file - -Copyright (c) 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EMMC_PEIM_MEM_H_ -#define _EMMC_PEIM_MEM_H_ - -#define EMMC_PEIM_MEM_BIT(a) ((UINTN)(1 << (a))) - -#define EMMC_PEIM_MEM_BIT_IS_SET(Data, Bit) \ - ((BOOLEAN)(((Data) & EMMC_PEIM_MEM_BIT(Bit)) == EMMC_PEIM_MEM_BIT(Bit))) - -typedef struct _EMMC_PEIM_MEM_BLOCK EMMC_PEIM_MEM_BLOCK; - -struct _EMMC_PEIM_MEM_BLOCK { - UINT8 *Bits; // Bit array to record which unit is allocated - UINTN BitsLen; - UINT8 *Buf; - UINTN BufLen; // Memory size in bytes - EMMC_PEIM_MEM_BLOCK *Next; -}; - -typedef struct _EMMC_PEIM_MEM_POOL { - EMMC_PEIM_MEM_BLOCK *Head; -} EMMC_PEIM_MEM_POOL; - -// -// Memory allocation unit, note that the value must meet EMMC spec alignment requirement. -// -#define EMMC_PEIM_MEM_UNIT 128 - -#define EMMC_PEIM_MEM_UNIT_MASK (EMMC_PEIM_MEM_UNIT - 1) -#define EMMC_PEIM_MEM_DEFAULT_PAGES 16 - -#define EMMC_PEIM_MEM_ROUND(Len) (((Len) + EMMC_PEIM_MEM_UNIT_MASK) & (~EMMC_PEIM_MEM_UNIT_MASK)) - -// -// Advance the byte and bit to the next bit, adjust byte accordingly. -// -#define EMMC_PEIM_NEXT_BIT(Byte, Bit) \ - do { \ - (Bit)++; \ - if ((Bit) > 7) { \ - (Byte)++; \ - (Bit) = 0; \ - } \ - } while (0) - -#endif - diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c deleted file mode 100644 index 7c40892da0..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c +++ /dev/null @@ -1,2878 +0,0 @@ -/** @file - - Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EmmcBlockIoPei.h" - -/** - Read/Write specified EMMC host controller mmio register. - - @param[in] Address The address of the mmio register to be read/written. - @param[in] Read A boolean to indicate it's read or write operation. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2 , 4 or 8 bytes. - @param[in, out] Data For read operations, the destination buffer to store - the results. For write operations, the source buffer - to write data from. The caller is responsible for - having ownership of the data buffer and ensuring its - size not less than Count bytes. - - @retval EFI_INVALID_PARAMETER The Address or the Data or the Count is not valid. - @retval EFI_SUCCESS The read/write operation succeeds. - @retval Others The read/write operation fails. - -**/ -EFI_STATUS -EFIAPI -EmmcPeimHcRwMmio ( - IN UINTN Address, - IN BOOLEAN Read, - IN UINT8 Count, - IN OUT VOID *Data - ) -{ - if ((Address == 0) || (Data == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Count != 1) && (Count != 2) && (Count != 4) && (Count != 8)) { - return EFI_INVALID_PARAMETER; - } - - switch (Count) { - case 1: - if (Read) { - *(UINT8*)Data = MmioRead8 (Address); - } else { - MmioWrite8 (Address, *(UINT8*)Data); - } - break; - case 2: - if (Read) { - *(UINT16*)Data = MmioRead16 (Address); - } else { - MmioWrite16 (Address, *(UINT16*)Data); - } - break; - case 4: - if (Read) { - *(UINT32*)Data = MmioRead32 (Address); - } else { - MmioWrite32 (Address, *(UINT32*)Data); - } - break; - case 8: - if (Read) { - *(UINT64*)Data = MmioRead64 (Address); - } else { - MmioWrite64 (Address, *(UINT64*)Data); - } - break; - default: - ASSERT (FALSE); - return EFI_INVALID_PARAMETER; - } - - return EFI_SUCCESS; -} - -/** - Do OR operation with the value of the specified EMMC host controller mmio register. - - @param[in] Address The address of the mmio register to be read/written. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2 , 4 or 8 bytes. - @param[in] OrData The pointer to the data used to do OR operation. - The caller is responsible for having ownership of - the data buffer and ensuring its size not less than - Count bytes. - - @retval EFI_INVALID_PARAMETER The Address or the OrData or the Count is not valid. - @retval EFI_SUCCESS The OR operation succeeds. - @retval Others The OR operation fails. - -**/ -EFI_STATUS -EFIAPI -EmmcPeimHcOrMmio ( - IN UINTN Address, - IN UINT8 Count, - IN VOID *OrData - ) -{ - EFI_STATUS Status; - UINT64 Data; - UINT64 Or; - - Status = EmmcPeimHcRwMmio (Address, TRUE, Count, &Data); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Count == 1) { - Or = *(UINT8*) OrData; - } else if (Count == 2) { - Or = *(UINT16*) OrData; - } else if (Count == 4) { - Or = *(UINT32*) OrData; - } else if (Count == 8) { - Or = *(UINT64*) OrData; - } else { - return EFI_INVALID_PARAMETER; - } - - Data |= Or; - Status = EmmcPeimHcRwMmio (Address, FALSE, Count, &Data); - - return Status; -} - -/** - Do AND operation with the value of the specified EMMC host controller mmio register. - - @param[in] Address The address of the mmio register to be read/written. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2 , 4 or 8 bytes. - @param[in] AndData The pointer to the data used to do AND operation. - The caller is responsible for having ownership of - the data buffer and ensuring its size not less than - Count bytes. - - @retval EFI_INVALID_PARAMETER The Address or the AndData or the Count is not valid. - @retval EFI_SUCCESS The AND operation succeeds. - @retval Others The AND operation fails. - -**/ -EFI_STATUS -EFIAPI -EmmcPeimHcAndMmio ( - IN UINTN Address, - IN UINT8 Count, - IN VOID *AndData - ) -{ - EFI_STATUS Status; - UINT64 Data; - UINT64 And; - - Status = EmmcPeimHcRwMmio (Address, TRUE, Count, &Data); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Count == 1) { - And = *(UINT8*) AndData; - } else if (Count == 2) { - And = *(UINT16*) AndData; - } else if (Count == 4) { - And = *(UINT32*) AndData; - } else if (Count == 8) { - And = *(UINT64*) AndData; - } else { - return EFI_INVALID_PARAMETER; - } - - Data &= And; - Status = EmmcPeimHcRwMmio (Address, FALSE, Count, &Data); - - return Status; -} - -/** - Wait for the value of the specified MMIO register set to the test value. - - @param[in] Address The address of the mmio register to be checked. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2, 4 or 8 bytes. - @param[in] MaskValue The mask value of memory. - @param[in] TestValue The test value of memory. - - @retval EFI_NOT_READY The MMIO register hasn't set to the expected value. - @retval EFI_SUCCESS The MMIO register has expected value. - @retval Others The MMIO operation fails. - -**/ -EFI_STATUS -EFIAPI -EmmcPeimHcCheckMmioSet ( - IN UINTN Address, - IN UINT8 Count, - IN UINT64 MaskValue, - IN UINT64 TestValue - ) -{ - EFI_STATUS Status; - UINT64 Value; - - // - // Access PCI MMIO space to see if the value is the tested one. - // - Value = 0; - Status = EmmcPeimHcRwMmio (Address, TRUE, Count, &Value); - if (EFI_ERROR (Status)) { - return Status; - } - - Value &= MaskValue; - - if (Value == TestValue) { - return EFI_SUCCESS; - } - - return EFI_NOT_READY; -} - -/** - Wait for the value of the specified MMIO register set to the test value. - - @param[in] Address The address of the mmio register to wait. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2, 4 or 8 bytes. - @param[in] MaskValue The mask value of memory. - @param[in] TestValue The test value of memory. - @param[in] Timeout The time out value for wait memory set, uses 1 - microsecond as a unit. - - @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout - range. - @retval EFI_SUCCESS The MMIO register has expected value. - @retval Others The MMIO operation fails. - -**/ -EFI_STATUS -EFIAPI -EmmcPeimHcWaitMmioSet ( - IN UINTN Address, - IN UINT8 Count, - IN UINT64 MaskValue, - IN UINT64 TestValue, - IN UINT64 Timeout - ) -{ - EFI_STATUS Status; - BOOLEAN InfiniteWait; - - if (Timeout == 0) { - InfiniteWait = TRUE; - } else { - InfiniteWait = FALSE; - } - - while (InfiniteWait || (Timeout > 0)) { - Status = EmmcPeimHcCheckMmioSet ( - Address, - Count, - MaskValue, - TestValue - ); - if (Status != EFI_NOT_READY) { - return Status; - } - - // - // Stall for 1 microsecond. - // - MicroSecondDelay (1); - - Timeout--; - } - - return EFI_TIMEOUT; -} - -/** - Software reset the specified EMMC host controller and enable all interrupts. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The software reset executes successfully. - @retval Others The software reset fails. - -**/ -EFI_STATUS -EmmcPeimHcReset ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT8 SwReset; - - SwReset = 0xFF; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_SW_RST, FALSE, sizeof (SwReset), &SwReset); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimHcReset: write full 1 fails: %r\n", Status)); - return Status; - } - - Status = EmmcPeimHcWaitMmioSet ( - Bar + EMMC_HC_SW_RST, - sizeof (SwReset), - 0xFF, - 0x00, - EMMC_TIMEOUT - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, "EmmcPeimHcReset: reset done with %r\n", Status)); - return Status; - } - // - // Enable all interrupt after reset all. - // - Status = EmmcPeimHcEnableInterrupt (Bar); - - return Status; -} - -/** - Set all interrupt status bits in Normal and Error Interrupt Status Enable - register. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The operation executes successfully. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimHcEnableInterrupt ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT16 IntStatus; - - // - // Enable all bits in Error Interrupt Status Enable Register - // - IntStatus = 0xFFFF; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_ERR_INT_STS_EN, FALSE, sizeof (IntStatus), &IntStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Enable all bits in Normal Interrupt Status Enable Register - // - IntStatus = 0xFFFF; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS_EN, FALSE, sizeof (IntStatus), &IntStatus); - - return Status; -} - -/** - Get the capability data from the specified slot. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[out] Capability The buffer to store the capability data. - - @retval EFI_SUCCESS The operation executes successfully. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimHcGetCapability ( - IN UINTN Bar, - OUT EMMC_HC_SLOT_CAP *Capability - ) -{ - EFI_STATUS Status; - UINT64 Cap; - - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_CAP, TRUE, sizeof (Cap), &Cap); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (Capability, &Cap, sizeof (Cap)); - - return EFI_SUCCESS; -} - -/** - Detect whether there is a EMMC card attached at the specified EMMC host controller - slot. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS There is a EMMC card attached. - @retval EFI_NO_MEDIA There is not a EMMC card attached. - @retval Others The detection fails. - -**/ -EFI_STATUS -EmmcPeimHcCardDetect ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT16 Data; - UINT32 PresentState; - - // - // Check Normal Interrupt Status Register - // - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, TRUE, sizeof (Data), &Data); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((Data & (BIT6 | BIT7)) != 0) { - // - // Clear BIT6 and BIT7 by writing 1 to these two bits if set. - // - Data &= BIT6 | BIT7; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (Data), &Data); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Check Present State Register to see if there is a card presented. - // - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((PresentState & BIT16) != 0) { - return EFI_SUCCESS; - } else { - return EFI_NO_MEDIA; - } -} - -/** - Stop EMMC card clock. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.2.2 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS Succeed to stop EMMC clock. - @retval Others Fail to stop EMMC clock. - -**/ -EFI_STATUS -EmmcPeimHcStopClock ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT32 PresentState; - UINT16 ClockCtrl; - - // - // Ensure no SD transactions are occurring on the SD Bus by - // waiting for Command Inhibit (DAT) and Command Inhibit (CMD) - // in the Present State register to be 0. - // - Status = EmmcPeimHcWaitMmioSet ( - Bar + EMMC_HC_PRESENT_STATE, - sizeof (PresentState), - BIT0 | BIT1, - 0, - EMMC_TIMEOUT - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Set SD Clock Enable in the Clock Control register to 0 - // - ClockCtrl = (UINT16)~BIT2; - Status = EmmcPeimHcAndMmio (Bar + EMMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl); - - return Status; -} - -/** - EMMC card clock supply. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.2.1 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] ClockFreq The max clock frequency to be set. The unit is KHz. - - @retval EFI_SUCCESS The clock is supplied successfully. - @retval Others The clock isn't supplied successfully. - -**/ -EFI_STATUS -EmmcPeimHcClockSupply ( - IN UINTN Bar, - IN UINT64 ClockFreq - ) -{ - EFI_STATUS Status; - EMMC_HC_SLOT_CAP Capability; - UINT32 BaseClkFreq; - UINT32 SettingFreq; - UINT32 Divisor; - UINT32 Remainder; - UINT16 ControllerVer; - UINT16 ClockCtrl; - - // - // Calculate a divisor for SD clock frequency - // - Status = EmmcPeimHcGetCapability (Bar, &Capability); - if (EFI_ERROR (Status)) { - return Status; - } - ASSERT (Capability.BaseClkFreq != 0); - - BaseClkFreq = Capability.BaseClkFreq; - - if (ClockFreq == 0) { - return EFI_INVALID_PARAMETER; - } - - if (ClockFreq > (BaseClkFreq * 1000)) { - ClockFreq = BaseClkFreq * 1000; - } - - // - // Calculate the divisor of base frequency. - // - Divisor = 0; - SettingFreq = BaseClkFreq * 1000; - while (ClockFreq < SettingFreq) { - Divisor++; - - SettingFreq = (BaseClkFreq * 1000) / (2 * Divisor); - Remainder = (BaseClkFreq * 1000) % (2 * Divisor); - if ((ClockFreq == SettingFreq) && (Remainder == 0)) { - break; - } - if ((ClockFreq == SettingFreq) && (Remainder != 0)) { - SettingFreq ++; - } - } - - DEBUG ((EFI_D_INFO, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq)); - - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register. - // - if ((ControllerVer & 0xFF) == 2) { - ASSERT (Divisor <= 0x3FF); - ClockCtrl = ((Divisor & 0xFF) << 8) | ((Divisor & 0x300) >> 2); - } else if (((ControllerVer & 0xFF) == 0) || ((ControllerVer & 0xFF) == 1)) { - // - // Only the most significant bit can be used as divisor. - // - if (((Divisor - 1) & Divisor) != 0) { - Divisor = 1 << (HighBitSet32 (Divisor) + 1); - } - ASSERT (Divisor <= 0x80); - ClockCtrl = (Divisor & 0xFF) << 8; - } else { - DEBUG ((EFI_D_ERROR, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer)); - return EFI_UNSUPPORTED; - } - - // - // Stop bus clock at first - // - Status = EmmcPeimHcStopClock (Bar); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Supply clock frequency with specified divisor - // - ClockCtrl |= BIT0; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_CLOCK_CTRL, FALSE, sizeof (ClockCtrl), &ClockCtrl); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n")); - return Status; - } - - // - // Wait Internal Clock Stable in the Clock Control register to be 1 - // - Status = EmmcPeimHcWaitMmioSet ( - Bar + EMMC_HC_CLOCK_CTRL, - sizeof (ClockCtrl), - BIT1, - BIT1, - EMMC_TIMEOUT - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Set SD Clock Enable in the Clock Control register to 1 - // - ClockCtrl = BIT2; - Status = EmmcPeimHcOrMmio (Bar + EMMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl); - - return Status; -} - -/** - EMMC bus power control. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] PowerCtrl The value setting to the power control register. - - @retval TRUE There is a EMMC card attached. - @retval FALSE There is no a EMMC card attached. - -**/ -EFI_STATUS -EmmcPeimHcPowerControl ( - IN UINTN Bar, - IN UINT8 PowerCtrl - ) -{ - EFI_STATUS Status; - - // - // Clr SD Bus Power - // - PowerCtrl &= (UINT8)~BIT0; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_POWER_CTRL, FALSE, sizeof (PowerCtrl), &PowerCtrl); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register - // - PowerCtrl |= BIT0; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_POWER_CTRL, FALSE, sizeof (PowerCtrl), &PowerCtrl); - - return Status; -} - -/** - Set the EMMC bus width. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] BusWidth The bus width used by the EMMC device, it must be 1, 4 or 8. - - @retval EFI_SUCCESS The bus width is set successfully. - @retval Others The bus width isn't set successfully. - -**/ -EFI_STATUS -EmmcPeimHcSetBusWidth ( - IN UINTN Bar, - IN UINT16 BusWidth - ) -{ - EFI_STATUS Status; - UINT8 HostCtrl1; - - if (BusWidth == 1) { - HostCtrl1 = (UINT8)~(BIT5 | BIT1); - Status = EmmcPeimHcAndMmio (Bar + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - } else if (BusWidth == 4) { - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_HOST_CTRL1, TRUE, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - HostCtrl1 |= BIT1; - HostCtrl1 &= (UINT8)~BIT5; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_HOST_CTRL1, FALSE, sizeof (HostCtrl1), &HostCtrl1); - } else if (BusWidth == 8) { - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_HOST_CTRL1, TRUE, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - HostCtrl1 &= (UINT8)~BIT1; - HostCtrl1 |= BIT5; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_HOST_CTRL1, FALSE, sizeof (HostCtrl1), &HostCtrl1); - } else { - ASSERT (FALSE); - return EFI_INVALID_PARAMETER; - } - - return Status; -} - -/** - Supply EMMC card with lowest clock frequency at initialization. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The clock is supplied successfully. - @retval Others The clock isn't supplied successfully. - -**/ -EFI_STATUS -EmmcPeimHcInitClockFreq ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - EMMC_HC_SLOT_CAP Capability; - UINT32 InitFreq; - - // - // Calculate a divisor for SD clock frequency - // - Status = EmmcPeimHcGetCapability (Bar, &Capability); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Capability.BaseClkFreq == 0) { - // - // Don't support get Base Clock Frequency information via another method - // - return EFI_UNSUPPORTED; - } - // - // Supply 400KHz clock frequency at initialization phase. - // - InitFreq = 400; - Status = EmmcPeimHcClockSupply (Bar, InitFreq); - return Status; -} - -/** - Supply EMMC card with maximum voltage at initialization. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The voltage is supplied successfully. - @retval Others The voltage isn't supplied successfully. - -**/ -EFI_STATUS -EmmcPeimHcInitPowerVoltage ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - EMMC_HC_SLOT_CAP Capability; - UINT8 MaxVoltage; - UINT8 HostCtrl2; - - // - // Get the support voltage of the Host Controller - // - Status = EmmcPeimHcGetCapability (Bar, &Capability); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Calculate supported maximum voltage according to SD Bus Voltage Select - // - if (Capability.Voltage33 != 0) { - // - // Support 3.3V - // - MaxVoltage = 0x0E; - } else if (Capability.Voltage30 != 0) { - // - // Support 3.0V - // - MaxVoltage = 0x0C; - } else if (Capability.Voltage18 != 0) { - // - // Support 1.8V - // - MaxVoltage = 0x0A; - HostCtrl2 = BIT3; - Status = EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - MicroSecondDelay (5000); - } else { - ASSERT (FALSE); - return EFI_DEVICE_ERROR; - } - - // - // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register - // - Status = EmmcPeimHcPowerControl (Bar, MaxVoltage); - - return Status; -} - -/** - Initialize the Timeout Control register with most conservative value at initialization. - - Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The timeout control register is configured successfully. - @retval Others The timeout control register isn't configured successfully. - -**/ -EFI_STATUS -EmmcPeimHcInitTimeoutCtrl ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT8 Timeout; - - Timeout = 0x0E; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_TIMEOUT_CTRL, FALSE, sizeof (Timeout), &Timeout); - - return Status; -} - -/** - Initial EMMC host controller with lowest clock frequency, max power and max timeout value - at initialization. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The host controller is initialized successfully. - @retval Others The host controller isn't initialized successfully. - -**/ -EFI_STATUS -EmmcPeimHcInitHost ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - - Status = EmmcPeimHcInitClockFreq (Bar); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcPeimHcInitPowerVoltage (Bar); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcPeimHcInitTimeoutCtrl (Bar); - return Status; -} - -/** - Turn on/off LED. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] On The boolean to turn on/off LED. - - @retval EFI_SUCCESS The LED is turned on/off successfully. - @retval Others The LED isn't turned on/off successfully. - -**/ -EFI_STATUS -EmmcPeimHcLedOnOff ( - IN UINTN Bar, - IN BOOLEAN On - ) -{ - EFI_STATUS Status; - UINT8 HostCtrl1; - - if (On) { - HostCtrl1 = BIT0; - Status = EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - } else { - HostCtrl1 = (UINT8)~BIT0; - Status = EmmcPeimHcAndMmio (Bar + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - } - - return Status; -} - -/** - Build ADMA descriptor table for transfer. - - Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details. - - @param[in] Trb The pointer to the EMMC_TRB instance. - - @retval EFI_SUCCESS The ADMA descriptor table is created successfully. - @retval Others The ADMA descriptor table isn't created successfully. - -**/ -EFI_STATUS -BuildAdmaDescTable ( - IN EMMC_TRB *Trb - ) -{ - EFI_PHYSICAL_ADDRESS Data; - UINT64 DataLen; - UINT64 Entries; - UINT32 Index; - UINT64 Remaining; - UINT32 Address; - - Data = (EFI_PHYSICAL_ADDRESS)(UINTN)Trb->Data; - DataLen = Trb->DataLen; - // - // Only support 32bit ADMA Descriptor Table - // - if ((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul)) { - return EFI_INVALID_PARAMETER; - } - // - // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0) - // for 32-bit address descriptor table. - // - if ((Data & (BIT0 | BIT1)) != 0) { - DEBUG ((EFI_D_INFO, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data)); - } - - Entries = DivU64x32 ((DataLen + ADMA_MAX_DATA_PER_LINE - 1), ADMA_MAX_DATA_PER_LINE); - - Trb->AdmaDescSize = (UINTN)MultU64x32 (Entries, sizeof (EMMC_HC_ADMA_DESC_LINE)); - Trb->AdmaDesc = EmmcPeimAllocateMem (Trb->Slot->Private->Pool, Trb->AdmaDescSize); - if (Trb->AdmaDesc == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Remaining = DataLen; - Address = (UINT32)Data; - for (Index = 0; Index < Entries; Index++) { - if (Remaining <= ADMA_MAX_DATA_PER_LINE) { - Trb->AdmaDesc[Index].Valid = 1; - Trb->AdmaDesc[Index].Act = 2; - Trb->AdmaDesc[Index].Length = (UINT16)Remaining; - Trb->AdmaDesc[Index].Address = Address; - break; - } else { - Trb->AdmaDesc[Index].Valid = 1; - Trb->AdmaDesc[Index].Act = 2; - Trb->AdmaDesc[Index].Length = 0; - Trb->AdmaDesc[Index].Address = Address; - } - - Remaining -= ADMA_MAX_DATA_PER_LINE; - Address += ADMA_MAX_DATA_PER_LINE; - } - - // - // Set the last descriptor line as end of descriptor table - // - Trb->AdmaDesc[Index].End = 1; - return EFI_SUCCESS; -} - -/** - Create a new TRB for the EMMC cmd request. - - @param[in] Slot The slot number of the EMMC card to send the command to. - @param[in] Packet A pointer to the SD command data structure. - - @return Created Trb or NULL. - -**/ -EMMC_TRB * -EmmcPeimCreateTrb ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN EMMC_COMMAND_PACKET *Packet - ) -{ - EMMC_TRB *Trb; - EFI_STATUS Status; - EMMC_HC_SLOT_CAP Capability; - - // - // Calculate a divisor for SD clock frequency - // - Status = EmmcPeimHcGetCapability (Slot->EmmcHcBase, &Capability); - if (EFI_ERROR (Status)) { - return NULL; - } - - Trb = EmmcPeimAllocateMem (Slot->Private->Pool, sizeof (EMMC_TRB)); - if (Trb == NULL) { - return NULL; - } - - Trb->Slot = Slot; - Trb->BlockSize = 0x200; - Trb->Packet = Packet; - Trb->Timeout = Packet->Timeout; - - if ((Packet->InTransferLength != 0) && (Packet->InDataBuffer != NULL)) { - Trb->Data = Packet->InDataBuffer; - Trb->DataLen = Packet->InTransferLength; - Trb->Read = TRUE; - } else if ((Packet->OutTransferLength != 0) && (Packet->OutDataBuffer != NULL)) { - Trb->Data = Packet->OutDataBuffer; - Trb->DataLen = Packet->OutTransferLength; - Trb->Read = FALSE; - } else if ((Packet->InTransferLength == 0) && (Packet->OutTransferLength == 0)) { - Trb->Data = NULL; - Trb->DataLen = 0; - } else { - goto Error; - } - - if ((Trb->DataLen != 0) && (Trb->DataLen < Trb->BlockSize)) { - Trb->BlockSize = (UINT16)Trb->DataLen; - } - - if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) { - Trb->Mode = EmmcPioMode; - } else { - if (Trb->DataLen == 0) { - Trb->Mode = EmmcNoData; - } else if (Capability.Adma2 != 0) { - Trb->Mode = EmmcAdmaMode; - Status = BuildAdmaDescTable (Trb); - if (EFI_ERROR (Status)) { - goto Error; - } - } else if (Capability.Sdma != 0) { - Trb->Mode = EmmcSdmaMode; - } else { - Trb->Mode = EmmcPioMode; - } - } - return Trb; - -Error: - EmmcPeimFreeTrb (Trb); - return NULL; -} - -/** - Free the resource used by the TRB. - - @param[in] Trb The pointer to the EMMC_TRB instance. - -**/ -VOID -EmmcPeimFreeTrb ( - IN EMMC_TRB *Trb - ) -{ - if ((Trb != NULL) && (Trb->AdmaDesc != NULL)) { - EmmcPeimFreeMem (Trb->Slot->Private->Pool, Trb->AdmaDesc, Trb->AdmaDescSize); - } - - if (Trb != NULL) { - EmmcPeimFreeMem (Trb->Slot->Private->Pool, Trb, sizeof (EMMC_TRB)); - } - return; -} - -/** - Check if the env is ready for execute specified TRB. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the EMMC_TRB instance. - - @retval EFI_SUCCESS The env is ready for TRB execution. - @retval EFI_NOT_READY The env is not ready for TRB execution. - @retval Others Some erros happen. - -**/ -EFI_STATUS -EmmcPeimCheckTrbEnv ( - IN UINTN Bar, - IN EMMC_TRB *Trb - ) -{ - EFI_STATUS Status; - EMMC_COMMAND_PACKET *Packet; - UINT32 PresentState; - - Packet = Trb->Packet; - - if ((Packet->EmmcCmdBlk->CommandType == EmmcCommandTypeAdtc) || - (Packet->EmmcCmdBlk->ResponseType == EmmcResponceTypeR1b) || - (Packet->EmmcCmdBlk->ResponseType == EmmcResponceTypeR5b)) { - // - // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in - // the Present State register to be 0 - // - PresentState = BIT0 | BIT1; - } else { - // - // Wait Command Inhibit (CMD) in the Present State register - // to be 0 - // - PresentState = BIT0; - } - - Status = EmmcPeimHcCheckMmioSet ( - Bar + EMMC_HC_PRESENT_STATE, - sizeof (PresentState), - PresentState, - 0 - ); - - return Status; -} - -/** - Wait for the env to be ready for execute specified TRB. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the EMMC_TRB instance. - - @retval EFI_SUCCESS The env is ready for TRB execution. - @retval EFI_TIMEOUT The env is not ready for TRB execution in time. - @retval Others Some erros happen. - -**/ -EFI_STATUS -EmmcPeimWaitTrbEnv ( - IN UINTN Bar, - IN EMMC_TRB *Trb - ) -{ - EFI_STATUS Status; - EMMC_COMMAND_PACKET *Packet; - UINT64 Timeout; - BOOLEAN InfiniteWait; - - // - // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register - // - Packet = Trb->Packet; - Timeout = Packet->Timeout; - if (Timeout == 0) { - InfiniteWait = TRUE; - } else { - InfiniteWait = FALSE; - } - - while (InfiniteWait || (Timeout > 0)) { - // - // Check Trb execution result by reading Normal Interrupt Status register. - // - Status = EmmcPeimCheckTrbEnv (Bar, Trb); - if (Status != EFI_NOT_READY) { - return Status; - } - // - // Stall for 1 microsecond. - // - MicroSecondDelay (1); - - Timeout--; - } - - return EFI_TIMEOUT; -} - -/** - Execute the specified TRB. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the EMMC_TRB instance. - - @retval EFI_SUCCESS The TRB is sent to host controller successfully. - @retval Others Some erros happen when sending this request to the host controller. - -**/ -EFI_STATUS -EmmcPeimExecTrb ( - IN UINTN Bar, - IN EMMC_TRB *Trb - ) -{ - EFI_STATUS Status; - EMMC_COMMAND_PACKET *Packet; - UINT16 Cmd; - UINT16 IntStatus; - UINT32 Argument; - UINT16 BlkCount; - UINT16 BlkSize; - UINT16 TransMode; - UINT8 HostCtrl1; - UINT32 SdmaAddr; - UINT64 AdmaAddr; - - Packet = Trb->Packet; - // - // Clear all bits in Error Interrupt Status Register - // - IntStatus = 0xFFFF; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_ERR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Clear all bits in Normal Interrupt Status Register - // - IntStatus = 0xFFFF; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set Host Control 1 register DMA Select field - // - if (Trb->Mode == EmmcAdmaMode) { - HostCtrl1 = BIT4; - Status = EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - } - - EmmcPeimHcLedOnOff (Bar, TRUE); - - if (Trb->Mode == EmmcSdmaMode) { - if ((UINT64)(UINTN)Trb->Data >= 0x100000000ul) { - return EFI_INVALID_PARAMETER; - } - - SdmaAddr = (UINT32)(UINTN)Trb->Data; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_SDMA_ADDR, FALSE, sizeof (SdmaAddr), &SdmaAddr); - if (EFI_ERROR (Status)) { - return Status; - } - } else if (Trb->Mode == EmmcAdmaMode) { - AdmaAddr = (UINT64)(UINTN)Trb->AdmaDesc; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_ADMA_SYS_ADDR, FALSE, sizeof (AdmaAddr), &AdmaAddr); - if (EFI_ERROR (Status)) { - return Status; - } - } - - BlkSize = Trb->BlockSize; - if (Trb->Mode == EmmcSdmaMode) { - // - // Set SDMA boundary to be 512K bytes. - // - BlkSize |= 0x7000; - } - - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_BLK_SIZE, FALSE, sizeof (BlkSize), &BlkSize); - if (EFI_ERROR (Status)) { - return Status; - } - - BlkCount = 0; - if (Trb->Mode != EmmcNoData) { - // - // Calcuate Block Count. - // - BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize); - } - - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount); - if (EFI_ERROR (Status)) { - return Status; - } - - Argument = Packet->EmmcCmdBlk->CommandArgument; - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_ARG1, FALSE, sizeof (Argument), &Argument); - if (EFI_ERROR (Status)) { - return Status; - } - - TransMode = 0; - if (Trb->Mode != EmmcNoData) { - if (Trb->Mode != EmmcPioMode) { - TransMode |= BIT0; - } - if (Trb->Read) { - TransMode |= BIT4; - } - if (BlkCount > 1) { - TransMode |= BIT5 | BIT1; - } - } - - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_TRANS_MOD, FALSE, sizeof (TransMode), &TransMode); - if (EFI_ERROR (Status)) { - return Status; - } - - Cmd = (UINT16)LShiftU64(Packet->EmmcCmdBlk->CommandIndex, 8); - if (Packet->EmmcCmdBlk->CommandType == EmmcCommandTypeAdtc) { - Cmd |= BIT5; - } - // - // Convert ResponseType to value - // - if (Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeBc) { - switch (Packet->EmmcCmdBlk->ResponseType) { - case EmmcResponceTypeR1: - case EmmcResponceTypeR5: - case EmmcResponceTypeR6: - case EmmcResponceTypeR7: - Cmd |= (BIT1 | BIT3 | BIT4); - break; - case EmmcResponceTypeR2: - Cmd |= (BIT0 | BIT3); - break; - case EmmcResponceTypeR3: - case EmmcResponceTypeR4: - Cmd |= BIT1; - break; - case EmmcResponceTypeR1b: - case EmmcResponceTypeR5b: - Cmd |= (BIT0 | BIT1 | BIT3 | BIT4); - break; - default: - ASSERT (FALSE); - break; - } - } - // - // Execute cmd - // - Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_COMMAND, FALSE, sizeof (Cmd), &Cmd); - return Status; -} - -/** - Check the TRB execution result. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the EMMC_TRB instance. - - @retval EFI_SUCCESS The TRB is executed successfully. - @retval EFI_NOT_READY The TRB is not completed for execution. - @retval Others Some erros happen when executing this request. - -**/ -EFI_STATUS -EmmcPeimCheckTrbResult ( - IN UINTN Bar, - IN EMMC_TRB *Trb - ) -{ - EFI_STATUS Status; - EMMC_COMMAND_PACKET *Packet; - UINT16 IntStatus; - UINT32 Response[4]; - UINT32 SdmaAddr; - UINT8 Index; - UINT8 SwReset; - UINT32 PioLength; - - SwReset = 0; - Packet = Trb->Packet; - // - // Check Trb execution result by reading Normal Interrupt Status register. - // - Status = EmmcPeimHcRwMmio ( - Bar + EMMC_HC_NOR_INT_STS, - TRUE, - sizeof (IntStatus), - &IntStatus - ); - if (EFI_ERROR (Status)) { - goto Done; - } - // - // Check Transfer Complete bit is set or not. - // - if ((IntStatus & BIT1) == BIT1) { - if ((IntStatus & BIT15) == BIT15) { - // - // Read Error Interrupt Status register to check if the error is - // Data Timeout Error. - // If yes, treat it as success as Transfer Complete has higher - // priority than Data Timeout Error. - // - Status = EmmcPeimHcRwMmio ( - Bar + EMMC_HC_ERR_INT_STS, - TRUE, - sizeof (IntStatus), - &IntStatus - ); - if (!EFI_ERROR (Status)) { - if ((IntStatus & BIT4) == BIT4) { - Status = EFI_SUCCESS; - } else { - Status = EFI_DEVICE_ERROR; - } - } - } - - goto Done; - } - // - // Check if there is a error happened during cmd execution. - // If yes, then do error recovery procedure to follow SD Host Controller - // Simplified Spec 3.0 section 3.10.1. - // - if ((IntStatus & BIT15) == BIT15) { - Status = EmmcPeimHcRwMmio ( - Bar + EMMC_HC_ERR_INT_STS, - TRUE, - sizeof (IntStatus), - &IntStatus - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - if ((IntStatus & 0x0F) != 0) { - SwReset |= BIT1; - } - if ((IntStatus & 0xF0) != 0) { - SwReset |= BIT2; - } - - Status = EmmcPeimHcRwMmio ( - Bar + EMMC_HC_SW_RST, - FALSE, - sizeof (SwReset), - &SwReset - ); - if (EFI_ERROR (Status)) { - goto Done; - } - Status = EmmcPeimHcWaitMmioSet ( - Bar + EMMC_HC_SW_RST, - sizeof (SwReset), - 0xFF, - 0, - EMMC_TIMEOUT - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = EFI_DEVICE_ERROR; - goto Done; - } - // - // Check if DMA interrupt is signalled for the SDMA transfer. - // - if ((Trb->Mode == EmmcSdmaMode) && ((IntStatus & BIT3) == BIT3)) { - // - // Clear DMA interrupt bit. - // - IntStatus = BIT3; - Status = EmmcPeimHcRwMmio ( - Bar + EMMC_HC_NOR_INT_STS, - FALSE, - sizeof (IntStatus), - &IntStatus - ); - if (EFI_ERROR (Status)) { - goto Done; - } - // - // Update SDMA Address register. - // - SdmaAddr = EMMC_SDMA_ROUND_UP ((UINT32)(UINTN)Trb->Data, EMMC_SDMA_BOUNDARY); - Status = EmmcPeimHcRwMmio ( - Bar + EMMC_HC_SDMA_ADDR, - FALSE, - sizeof (UINT32), - &SdmaAddr - ); - if (EFI_ERROR (Status)) { - goto Done; - } - Trb->Data = (VOID*)(UINTN)SdmaAddr; - } - - if ((Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeAdtc) && - (Packet->EmmcCmdBlk->ResponseType != EmmcResponceTypeR1b) && - (Packet->EmmcCmdBlk->ResponseType != EmmcResponceTypeR5b)) { - if ((IntStatus & BIT0) == BIT0) { - Status = EFI_SUCCESS; - goto Done; - } - } - - if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) { - // - // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode, - // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1. - // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details. - // - if ((IntStatus & BIT5) == BIT5) { - // - // Clear Buffer Read Ready interrupt at first. - // - IntStatus = BIT5; - EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus); - // - // Read data out from Buffer Port register - // - for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) { - EmmcPeimHcRwMmio (Bar + EMMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength); - } - Status = EFI_SUCCESS; - goto Done; - } - } - - Status = EFI_NOT_READY; -Done: - // - // Get response data when the cmd is executed successfully. - // - if (!EFI_ERROR (Status)) { - if (Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeBc) { - for (Index = 0; Index < 4; Index++) { - Status = EmmcPeimHcRwMmio ( - Bar + EMMC_HC_RESPONSE + Index * 4, - TRUE, - sizeof (UINT32), - &Response[Index] - ); - if (EFI_ERROR (Status)) { - EmmcPeimHcLedOnOff (Bar, FALSE); - return Status; - } - } - CopyMem (Packet->EmmcStatusBlk, Response, sizeof (Response)); - } - } - - if (Status != EFI_NOT_READY) { - EmmcPeimHcLedOnOff (Bar, FALSE); - } - - return Status; -} - -/** - Wait for the TRB execution result. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the EMMC_TRB instance. - - @retval EFI_SUCCESS The TRB is executed successfully. - @retval Others Some erros happen when executing this request. - -**/ -EFI_STATUS -EmmcPeimWaitTrbResult ( - IN UINTN Bar, - IN EMMC_TRB *Trb - ) -{ - EFI_STATUS Status; - EMMC_COMMAND_PACKET *Packet; - UINT64 Timeout; - BOOLEAN InfiniteWait; - - Packet = Trb->Packet; - // - // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register - // - Timeout = Packet->Timeout; - if (Timeout == 0) { - InfiniteWait = TRUE; - } else { - InfiniteWait = FALSE; - } - - while (InfiniteWait || (Timeout > 0)) { - // - // Check Trb execution result by reading Normal Interrupt Status register. - // - Status = EmmcPeimCheckTrbResult (Bar, Trb); - if (Status != EFI_NOT_READY) { - return Status; - } - // - // Stall for 1 microsecond. - // - MicroSecondDelay (1); - - Timeout--; - } - - return EFI_TIMEOUT; -} - -/** - Sends EMMC command to an EMMC card that is attached to the EMMC controller. - - If Packet is successfully sent to the EMMC card, then EFI_SUCCESS is returned. - - If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned. - - If Slot is not in a valid range for the EMMC controller, then EFI_INVALID_PARAMETER - is returned. - - If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL, - EFI_INVALID_PARAMETER is returned. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in,out] Packet A pointer to the EMMC command data structure. - - @retval EFI_SUCCESS The EMMC Command Packet was sent by the host. - @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD - command Packet. - @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid. - @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and - OutDataBuffer are NULL. - @retval EFI_NO_MEDIA SD Device not present in the Slot. - @retval EFI_UNSUPPORTED The command described by the EMMC Command Packet is not - supported by the host controller. - @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the - limit supported by EMMC card ( i.e. if the number of bytes - exceed the Last LBA). - -**/ -EFI_STATUS -EFIAPI -EmmcPeimExecCmd ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN OUT EMMC_COMMAND_PACKET *Packet - ) -{ - EFI_STATUS Status; - EMMC_TRB *Trb; - - if (Packet == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->EmmcCmdBlk == NULL) || (Packet->EmmcStatusBlk == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->OutDataBuffer == NULL) && (Packet->OutTransferLength != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->InDataBuffer == NULL) && (Packet->InTransferLength != 0)) { - return EFI_INVALID_PARAMETER; - } - - Trb = EmmcPeimCreateTrb (Slot, Packet); - if (Trb == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = EmmcPeimWaitTrbEnv (Slot->EmmcHcBase, Trb); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = EmmcPeimExecTrb (Slot->EmmcHcBase, Trb); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = EmmcPeimWaitTrbResult (Slot->EmmcHcBase, Trb); - if (EFI_ERROR (Status)) { - goto Done; - } - -Done: - EmmcPeimFreeTrb (Trb); - - return Status; -} - -/** - Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to - make it go to Idle State. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - - @retval EFI_SUCCESS The EMMC device is reset correctly. - @retval Others The device reset fails. - -**/ -EFI_STATUS -EmmcPeimReset ( - IN EMMC_PEIM_HC_SLOT *Slot - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_GO_IDLE_STATE; - EmmcCmdBlk.CommandType = EmmcCommandTypeBc; - EmmcCmdBlk.ResponseType = 0; - EmmcCmdBlk.CommandArgument = 0; - - Status = EmmcPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SEND_OP_COND to the EMMC device to get the data of the OCR register. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device. - On output, the argument is the value of OCR register. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimGetOcr ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN OUT UINT32 *Argument - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SEND_OP_COND; - EmmcCmdBlk.CommandType = EmmcCommandTypeBcr; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR3; - EmmcCmdBlk.CommandArgument = *Argument; - - Status = EmmcPeimExecCmd (Slot, &Packet); - if (!EFI_ERROR (Status)) { - // - // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. - // - *Argument = EmmcStatusBlk.Resp0; - } - - return Status; -} - -/** - Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the - data of their CID registers. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimGetAllCid ( - IN EMMC_PEIM_HC_SLOT *Slot - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_ALL_SEND_CID; - EmmcCmdBlk.CommandType = EmmcCommandTypeBcr; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR2; - EmmcCmdBlk.CommandArgument = 0; - - Status = EmmcPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device - Address (RCA). - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address to be assigned. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSetRca ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SET_RELATIVE_ADDR; - EmmcCmdBlk.CommandType = EmmcCommandTypeAc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1; - EmmcCmdBlk.CommandArgument = Rca << 16; - - Status = EmmcPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SEND_CSD to the EMMC device to get the data of the CSD register. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address of selected device. - @param[out] Csd The buffer to store the content of the CSD register. - Note the caller should ignore the lowest byte of this - buffer as the content of this byte is meaningless even - if the operation succeeds. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimGetCsd ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca, - OUT EMMC_CSD *Csd - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SEND_CSD; - EmmcCmdBlk.CommandType = EmmcCommandTypeAc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR2; - EmmcCmdBlk.CommandArgument = Rca << 16; - - Status = EmmcPeimExecCmd (Slot, &Packet); - if (!EFI_ERROR (Status)) { - // - // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. - // - CopyMem (((UINT8*)Csd) + 1, &EmmcStatusBlk.Resp0, sizeof (EMMC_CSD) - 1); - } - - return Status; -} - -/** - Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address of selected device. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSelect ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SELECT_DESELECT_CARD; - EmmcCmdBlk.CommandType = EmmcCommandTypeAc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1; - EmmcCmdBlk.CommandArgument = Rca << 16; - - Status = EmmcPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[out] ExtCsd The buffer to store the content of the EXT_CSD register. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimGetExtCsd ( - IN EMMC_PEIM_HC_SLOT *Slot, - OUT EMMC_EXT_CSD *ExtCsd - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SEND_EXT_CSD; - EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1; - EmmcCmdBlk.CommandArgument = 0x00000000; - - Packet.InDataBuffer = ExtCsd; - Packet.InTransferLength = sizeof (EMMC_EXT_CSD); - - Status = EmmcPeimExecCmd (Slot, &Packet); - return Status; -} - -/** - Send command SWITCH to the EMMC device to switch the mode of operation of the - selected Device or modifies the EXT_CSD registers. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Access The access mode of SWTICH command. - @param[in] Index The offset of the field to be access. - @param[in] Value The value to be set to the specified field of EXT_CSD register. - @param[in] CmdSet The value of CmdSet field of EXT_CSD register. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSwitch ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT8 Access, - IN UINT8 Index, - IN UINT8 Value, - IN UINT8 CmdSet - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SWITCH; - EmmcCmdBlk.CommandType = EmmcCommandTypeAc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1b; - EmmcCmdBlk.CommandArgument = (Access << 24) | (Index << 16) | (Value << 8) | CmdSet; - - Status = EmmcPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SEND_STATUS to the addressed EMMC device to get its status register. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address of addressed device. - @param[out] DevStatus The returned device status. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSendStatus ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca, - OUT UINT32 *DevStatus - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SEND_STATUS; - EmmcCmdBlk.CommandType = EmmcCommandTypeAc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1; - EmmcCmdBlk.CommandArgument = Rca << 16; - - Status = EmmcPeimExecCmd (Slot, &Packet); - if (!EFI_ERROR (Status)) { - *DevStatus = EmmcStatusBlk.Resp0; - } - - return Status; -} - -/** - Send command SET_BLOCK_COUNT to the addressed EMMC device to set the number of - blocks for the following block read/write cmd. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] BlockCount The number of the logical block to access. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSetBlkCount ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT16 BlockCount - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SET_BLOCK_COUNT; - EmmcCmdBlk.CommandType = EmmcCommandTypeAc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1; - EmmcCmdBlk.CommandArgument = BlockCount; - - Status = EmmcPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed EMMC device - to read/write the specified number of blocks. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Lba The logical block address of starting access. - @param[in] BlockSize The block size of specified EMMC device partition. - @param[in] Buffer The pointer to the transfer buffer. - @param[in] BufferSize The size of transfer buffer. - @param[in] IsRead Boolean to show the operation direction. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimRwMultiBlocks ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN EFI_LBA Lba, - IN UINT32 BlockSize, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - // - // Calculate timeout value through the below formula. - // Timeout = (transfer size) / (2MB/s). - // Taking 2MB/s as divisor is because it's nearest to the eMMC lowest - // transfer speed (2.4MB/s). - // Refer to eMMC 5.0 spec section 6.9.1 for details. - // - Packet.Timeout = (BufferSize / (2 * 1024 * 1024) + 1) * 1000 * 1000;; - - if (IsRead) { - Packet.InDataBuffer = Buffer; - Packet.InTransferLength = (UINT32)BufferSize; - - EmmcCmdBlk.CommandIndex = EMMC_READ_MULTIPLE_BLOCK; - EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1; - } else { - Packet.OutDataBuffer = Buffer; - Packet.OutTransferLength = (UINT32)BufferSize; - - EmmcCmdBlk.CommandIndex = EMMC_WRITE_MULTIPLE_BLOCK; - EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1; - } - - if (Slot->SectorAddressing) { - EmmcCmdBlk.CommandArgument = (UINT32)Lba; - } else { - EmmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (Lba, BlockSize); - } - - Status = EmmcPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point - detection. - - It may be sent up to 40 times until the host finishes the tuning procedure. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] BusWidth The bus width to work. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSendTuningBlk ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT8 BusWidth - ) -{ - EMMC_COMMAND_BLOCK EmmcCmdBlk; - EMMC_STATUS_BLOCK EmmcStatusBlk; - EMMC_COMMAND_PACKET Packet; - EFI_STATUS Status; - UINT8 TuningBlock[128]; - - ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk)); - ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.EmmcCmdBlk = &EmmcCmdBlk; - Packet.EmmcStatusBlk = &EmmcStatusBlk; - Packet.Timeout = EMMC_TIMEOUT; - - EmmcCmdBlk.CommandIndex = EMMC_SEND_TUNING_BLOCK; - EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc; - EmmcCmdBlk.ResponseType = EmmcResponceTypeR1; - EmmcCmdBlk.CommandArgument = 0; - - Packet.InDataBuffer = TuningBlock; - if (BusWidth == 8) { - Packet.InTransferLength = sizeof (TuningBlock); - } else { - Packet.InTransferLength = 64; - } - - Status = EmmcPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Tunning the clock to get HS200 optimal sampling point. - - Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the - tuning procedure. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller - Simplified Spec 3.0 section Figure 2-29 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] BusWidth The bus width to work. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimTuningClkForHs200 ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT8 BusWidth - ) -{ - EFI_STATUS Status; - UINT8 HostCtrl2; - UINT8 Retry; - - // - // Notify the host that the sampling clock tuning procedure starts. - // - HostCtrl2 = BIT6; - Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Ask the device to send a sequence of tuning blocks till the tuning procedure is done. - // - Retry = 0; - do { - Status = EmmcPeimSendTuningBlk (Slot, BusWidth); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcPeimHcRwMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((HostCtrl2 & (BIT6 | BIT7)) == 0) { - break; - } - - if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) { - return EFI_SUCCESS; - } - } while (++Retry < 40); - - DEBUG ((EFI_D_ERROR, "EmmcPeimTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2)); - // - // Abort the tuning procedure and reset the tuning circuit. - // - HostCtrl2 = (UINT8)~(BIT6 | BIT7); - Status = EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - return EFI_DEVICE_ERROR; -} - -/** - Switch the bus width to specified width. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller - Simplified Spec 3.0 section Figure 3-7 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address to be assigned. - @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise - use single data rate data simpling method. - @param[in] BusWidth The bus width to be set, it could be 4 or 8. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSwitchBusWidth ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca, - IN BOOLEAN IsDdr, - IN UINT8 BusWidth - ) -{ - EFI_STATUS Status; - UINT8 Access; - UINT8 Index; - UINT8 Value; - UINT8 CmdSet; - UINT32 DevStatus; - - // - // Write Byte, the Value field is written into the byte pointed by Index. - // - Access = 0x03; - Index = OFFSET_OF (EMMC_EXT_CSD, BusWidth); - if (BusWidth == 4) { - Value = 1; - } else if (BusWidth == 8) { - Value = 2; - } else { - return EFI_INVALID_PARAMETER; - } - - if (IsDdr) { - Value += 4; - } - - CmdSet = 0; - Status = EmmcPeimSwitch (Slot, Access, Index, Value, CmdSet); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcPeimSendStatus (Slot, Rca, &DevStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Check the switch operation is really successful or not. - // - if ((DevStatus & BIT7) != 0) { - return EFI_DEVICE_ERROR; - } - - Status = EmmcPeimHcSetBusWidth (Slot->EmmcHcBase, BusWidth); - - return Status; -} - -/** - Switch the clock frequency to the specified value. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller - Simplified Spec 3.0 section Figure 3-3 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address to be assigned. - @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register. - @param[in] ClockFreq The max clock frequency to be set, the unit is MHz. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSwitchClockFreq ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca, - IN UINT8 HsTiming, - IN UINT32 ClockFreq - ) -{ - EFI_STATUS Status; - UINT8 Access; - UINT8 Index; - UINT8 Value; - UINT8 CmdSet; - UINT32 DevStatus; - - // - // Write Byte, the Value field is written into the byte pointed by Index. - // - Access = 0x03; - Index = OFFSET_OF (EMMC_EXT_CSD, HsTiming); - Value = HsTiming; - CmdSet = 0; - - Status = EmmcPeimSwitch (Slot, Access, Index, Value, CmdSet); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcPeimSendStatus (Slot, Rca, &DevStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Check the switch operation is really successful or not. - // - if ((DevStatus & BIT7) != 0) { - return EFI_DEVICE_ERROR; - } - // - // Convert the clock freq unit from MHz to KHz. - // - Status = EmmcPeimHcClockSupply (Slot->EmmcHcBase, ClockFreq * 1000); - - return Status; -} - -/** - Switch to the High Speed timing according to request. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller - Simplified Spec 3.0 section Figure 2-29 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address to be assigned. - @param[in] ClockFreq The max clock frequency to be set. - @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise - use single data rate data simpling method. - @param[in] BusWidth The bus width to be set, it could be 4 or 8. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSwitchToHighSpeed ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca, - IN UINT32 ClockFreq, - IN BOOLEAN IsDdr, - IN UINT8 BusWidth - ) -{ - EFI_STATUS Status; - UINT8 HsTiming; - UINT8 HostCtrl1; - UINT8 HostCtrl2; - - Status = EmmcPeimSwitchBusWidth (Slot, Rca, IsDdr, BusWidth); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set to Hight Speed timing - // - HostCtrl1 = BIT2; - Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - - HostCtrl2 = (UINT8)~0x7; - Status = EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - if (IsDdr) { - HostCtrl2 = BIT2; - } else if (ClockFreq == 52) { - HostCtrl2 = BIT0; - } else { - HostCtrl2 = 0; - } - Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - - HsTiming = 1; - Status = EmmcPeimSwitchClockFreq (Slot, Rca, HsTiming, ClockFreq); - - return Status; -} - -/** - Switch to the HS200 timing according to request. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller - Simplified Spec 3.0 section Figure 2-29 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address to be assigned. - @param[in] ClockFreq The max clock frequency to be set. - @param[in] BusWidth The bus width to be set, it could be 4 or 8. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSwitchToHS200 ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca, - IN UINT32 ClockFreq, - IN UINT8 BusWidth - ) -{ - EFI_STATUS Status; - UINT8 HsTiming; - UINT8 HostCtrl2; - UINT16 ClockCtrl; - - if ((BusWidth != 4) && (BusWidth != 8)) { - return EFI_INVALID_PARAMETER; - } - - Status = EmmcPeimSwitchBusWidth (Slot, Rca, FALSE, BusWidth); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set to HS200/SDR104 timing - // - // - // Stop bus clock at first - // - Status = EmmcPeimHcStopClock (Slot->EmmcHcBase); - if (EFI_ERROR (Status)) { - return Status; - } - - HostCtrl2 = (UINT8)~0x7; - Status = EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - HostCtrl2 = BIT0 | BIT1; - Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit - // - Status = EmmcPeimHcWaitMmioSet ( - Slot->EmmcHcBase + EMMC_HC_CLOCK_CTRL, - sizeof (ClockCtrl), - BIT1, - BIT1, - EMMC_TIMEOUT - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set SD Clock Enable in the Clock Control register to 1 - // - ClockCtrl = BIT2; - Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl); - - HsTiming = 2; - Status = EmmcPeimSwitchClockFreq (Slot, Rca, HsTiming, ClockFreq); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcPeimTuningClkForHs200 (Slot, BusWidth); - - return Status; -} - -/** - Switch to the HS400 timing according to request. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller - Simplified Spec 3.0 section Figure 2-29 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address to be assigned. - @param[in] ClockFreq The max clock frequency to be set. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSwitchToHS400 ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca, - IN UINT32 ClockFreq - ) -{ - EFI_STATUS Status; - UINT8 HsTiming; - UINT8 HostCtrl2; - - Status = EmmcPeimSwitchToHS200 (Slot, Rca, ClockFreq, 8); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz. - // - HsTiming = 1; - Status = EmmcPeimSwitchClockFreq (Slot, Rca, HsTiming, 52); - if (EFI_ERROR (Status)) { - return Status; - } - // - // HS400 mode must use 8 data lines. - // - Status = EmmcPeimSwitchBusWidth (Slot, Rca, TRUE, 8); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set to HS400 timing - // - HostCtrl2 = (UINT8)~0x7; - Status = EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - HostCtrl2 = BIT0 | BIT2; - Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - - HsTiming = 3; - Status = EmmcPeimSwitchClockFreq (Slot, Rca, HsTiming, ClockFreq); - - return Status; -} - -/** - Switch the high speed timing according to request. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller - Simplified Spec 3.0 section Figure 2-29 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Rca The relative device address to be assigned. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSetBusMode ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT32 Rca - ) -{ - EFI_STATUS Status; - EMMC_HC_SLOT_CAP Capability; - UINT8 HsTiming; - BOOLEAN IsDdr; - UINT32 ClockFreq; - UINT8 BusWidth; - - Status = EmmcPeimGetCsd (Slot, Rca, &Slot->Csd); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimSetBusMode: EmmcPeimGetCsd fails with %r\n", Status)); - return Status; - } - - if ((Slot->Csd.CSizeLow | Slot->Csd.CSizeHigh << 2) == 0xFFF) { - Slot->SectorAddressing = TRUE; - } else { - Slot->SectorAddressing = FALSE; - } - - Status = EmmcPeimSelect (Slot, Rca); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimSetBusMode: EmmcPeimSelect fails with %r\n", Status)); - return Status; - } - - Status = EmmcPeimHcGetCapability (Slot->EmmcHcBase, &Capability); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimSetBusMode: EmmcPeimHcGetCapability fails with %r\n", Status)); - return Status; - } - - ASSERT (Capability.BaseClkFreq != 0); - // - // Check if the Host Controller support 8bits bus width. - // - if (Capability.BusWidth8 != 0) { - BusWidth = 8; - } else { - BusWidth = 4; - } - // - // Get Deivce_Type from EXT_CSD register. - // - Status = EmmcPeimGetExtCsd (Slot, &Slot->ExtCsd); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimSetBusMode: EmmcPeimGetExtCsd fails with %r\n", Status)); - return Status; - } - // - // Calculate supported bus speed/bus width/clock frequency. - // - HsTiming = 0; - IsDdr = FALSE; - ClockFreq = 0; - if (((Slot->ExtCsd.DeviceType & (BIT4 | BIT5)) != 0) && (Capability.Sdr104 != 0)) { - HsTiming = 2; - IsDdr = FALSE; - ClockFreq = 200; - } else if (((Slot->ExtCsd.DeviceType & (BIT2 | BIT3)) != 0) && (Capability.Ddr50 != 0)) { - HsTiming = 1; - IsDdr = TRUE; - ClockFreq = 52; - } else if (((Slot->ExtCsd.DeviceType & BIT1) != 0) && (Capability.HighSpeed != 0)) { - HsTiming = 1; - IsDdr = FALSE; - ClockFreq = 52; - } else if (((Slot->ExtCsd.DeviceType & BIT0) != 0) && (Capability.HighSpeed != 0)) { - HsTiming = 1; - IsDdr = FALSE; - ClockFreq = 26; - } - // - // Check if both of the device and the host controller support HS400 DDR mode. - // - if (((Slot->ExtCsd.DeviceType & (BIT6 | BIT7)) != 0) && (Capability.Hs400 != 0)) { - // - // The host controller supports 8bits bus. - // - ASSERT (BusWidth == 8); - HsTiming = 3; - IsDdr = TRUE; - ClockFreq = 200; - } - - if ((ClockFreq == 0) || (HsTiming == 0)) { - // - // Continue using default setting. - // - return EFI_SUCCESS; - } - - DEBUG ((EFI_D_INFO, "HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming, ClockFreq, BusWidth, IsDdr ? "TRUE":"FALSE")); - - if (HsTiming == 3) { - // - // Execute HS400 timing switch procedure - // - Status = EmmcPeimSwitchToHS400 (Slot, Rca, ClockFreq); - } else if (HsTiming == 2) { - // - // Execute HS200 timing switch procedure - // - Status = EmmcPeimSwitchToHS200 (Slot, Rca, ClockFreq, BusWidth); - } else { - // - // Execute High Speed timing switch procedure - // - Status = EmmcPeimSwitchToHighSpeed (Slot, Rca, ClockFreq, IsDdr, BusWidth); - } - - return Status; -} - -/** - Execute EMMC device identification procedure. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - - @retval EFI_SUCCESS There is a EMMC card. - @retval Others There is not a EMMC card. - -**/ -EFI_STATUS -EmmcPeimIdentification ( - IN EMMC_PEIM_HC_SLOT *Slot - ) -{ - EFI_STATUS Status; - UINT32 Ocr; - UINT32 Rca; - UINTN Retry; - - Status = EmmcPeimReset (Slot); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimReset fails with %r\n", Status)); - return Status; - } - - Ocr = 0; - Retry = 0; - do { - Status = EmmcPeimGetOcr (Slot, &Ocr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimGetOcr fails with %r\n", Status)); - return Status; - } - - if (Retry++ == 100) { - DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimGetOcr fails too many times\n")); - return EFI_DEVICE_ERROR; - } - MicroSecondDelay (10 * 1000); - } while ((Ocr & BIT31) == 0); - - Status = EmmcPeimGetAllCid (Slot); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimGetAllCid fails with %r\n", Status)); - return Status; - } - // - // Don't support multiple devices on the slot, that is - // shared bus slot feature. - // - Rca = 1; - Status = EmmcPeimSetRca (Slot, Rca); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimSetRca fails with %r\n", Status)); - return Status; - } - // - // Enter Data Tranfer Mode. - // - DEBUG ((EFI_D_INFO, "Found a EMMC device at slot [%d], RCA [%d]\n", Slot, Rca)); - - Status = EmmcPeimSetBusMode (Slot, Rca); - - return Status; -} - diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.h b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.h deleted file mode 100644 index a74f1c6b99..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.h +++ /dev/null @@ -1,345 +0,0 @@ -/** @file - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EMMC_HCI_H_ -#define _EMMC_HCI_H_ - -// -// EMMC Host Controller MMIO Register Offset -// -#define EMMC_HC_SDMA_ADDR 0x00 -#define EMMC_HC_ARG2 0x00 -#define EMMC_HC_BLK_SIZE 0x04 -#define EMMC_HC_BLK_COUNT 0x06 -#define EMMC_HC_ARG1 0x08 -#define EMMC_HC_TRANS_MOD 0x0C -#define EMMC_HC_COMMAND 0x0E -#define EMMC_HC_RESPONSE 0x10 -#define EMMC_HC_BUF_DAT_PORT 0x20 -#define EMMC_HC_PRESENT_STATE 0x24 -#define EMMC_HC_HOST_CTRL1 0x28 -#define EMMC_HC_POWER_CTRL 0x29 -#define EMMC_HC_BLK_GAP_CTRL 0x2A -#define EMMC_HC_WAKEUP_CTRL 0x2B -#define EMMC_HC_CLOCK_CTRL 0x2C -#define EMMC_HC_TIMEOUT_CTRL 0x2E -#define EMMC_HC_SW_RST 0x2F -#define EMMC_HC_NOR_INT_STS 0x30 -#define EMMC_HC_ERR_INT_STS 0x32 -#define EMMC_HC_NOR_INT_STS_EN 0x34 -#define EMMC_HC_ERR_INT_STS_EN 0x36 -#define EMMC_HC_NOR_INT_SIG_EN 0x38 -#define EMMC_HC_ERR_INT_SIG_EN 0x3A -#define EMMC_HC_AUTO_CMD_ERR_STS 0x3C -#define EMMC_HC_HOST_CTRL2 0x3E -#define EMMC_HC_CAP 0x40 -#define EMMC_HC_MAX_CURRENT_CAP 0x48 -#define EMMC_HC_FORCE_EVT_AUTO_CMD 0x50 -#define EMMC_HC_FORCE_EVT_ERR_INT 0x52 -#define EMMC_HC_ADMA_ERR_STS 0x54 -#define EMMC_HC_ADMA_SYS_ADDR 0x58 -#define EMMC_HC_PRESET_VAL 0x60 -#define EMMC_HC_SHARED_BUS_CTRL 0xE0 -#define EMMC_HC_SLOT_INT_STS 0xFC -#define EMMC_HC_CTRL_VER 0xFE - -// -// The transfer modes supported by SD Host Controller -// Simplified Spec 3.0 Table 1-2 -// -typedef enum { - EmmcNoData, - EmmcPioMode, - EmmcSdmaMode, - EmmcAdmaMode -} EMMC_HC_TRANSFER_MODE; - -// -// The maximum data length of each descriptor line -// -#define ADMA_MAX_DATA_PER_LINE 0x10000 -#define EMMC_SDMA_BOUNDARY 512 * 1024 -#define EMMC_SDMA_ROUND_UP(x, n) (((x) + n) & ~(n - 1)) - -typedef enum { - EmmcCommandTypeBc, // Broadcast commands, no response - EmmcCommandTypeBcr, // Broadcast commands with response - EmmcCommandTypeAc, // Addressed(point-to-point) commands - EmmcCommandTypeAdtc // Addressed(point-to-point) data transfer commands -} EMMC_COMMAND_TYPE; - -typedef enum { - EmmcResponceTypeR1, - EmmcResponceTypeR1b, - EmmcResponceTypeR2, - EmmcResponceTypeR3, - EmmcResponceTypeR4, - EmmcResponceTypeR5, - EmmcResponceTypeR5b, - EmmcResponceTypeR6, - EmmcResponceTypeR7 -} EMMC_RESPONSE_TYPE; - -typedef struct _EMMC_COMMAND_BLOCK { - UINT16 CommandIndex; - UINT32 CommandArgument; - UINT32 CommandType; // One of the EMMC_COMMAND_TYPE values - UINT32 ResponseType; // One of the EMMC_RESPONSE_TYPE values -} EMMC_COMMAND_BLOCK; - -typedef struct _EMMC_STATUS_BLOCK { - UINT32 Resp0; - UINT32 Resp1; - UINT32 Resp2; - UINT32 Resp3; -} EMMC_STATUS_BLOCK; - -typedef struct _EMMC_COMMAND_PACKET { - UINT64 Timeout; - EMMC_COMMAND_BLOCK *EmmcCmdBlk; - EMMC_STATUS_BLOCK *EmmcStatusBlk; - VOID *InDataBuffer; - VOID *OutDataBuffer; - UINT32 InTransferLength; - UINT32 OutTransferLength; -} EMMC_COMMAND_PACKET; - -#pragma pack(1) - -typedef struct { - UINT32 Valid:1; - UINT32 End:1; - UINT32 Int:1; - UINT32 Reserved:1; - UINT32 Act:2; - UINT32 Reserved1:10; - UINT32 Length:16; - UINT32 Address; -} EMMC_HC_ADMA_DESC_LINE; - -typedef struct { - UINT32 TimeoutFreq:6; // bit 0:5 - UINT32 Reserved:1; // bit 6 - UINT32 TimeoutUnit:1; // bit 7 - UINT32 BaseClkFreq:8; // bit 8:15 - UINT32 MaxBlkLen:2; // bit 16:17 - UINT32 BusWidth8:1; // bit 18 - UINT32 Adma2:1; // bit 19 - UINT32 Reserved2:1; // bit 20 - UINT32 HighSpeed:1; // bit 21 - UINT32 Sdma:1; // bit 22 - UINT32 SuspRes:1; // bit 23 - UINT32 Voltage33:1; // bit 24 - UINT32 Voltage30:1; // bit 25 - UINT32 Voltage18:1; // bit 26 - UINT32 Reserved3:1; // bit 27 - UINT32 SysBus64:1; // bit 28 - UINT32 AsyncInt:1; // bit 29 - UINT32 SlotType:2; // bit 30:31 - UINT32 Sdr50:1; // bit 32 - UINT32 Sdr104:1; // bit 33 - UINT32 Ddr50:1; // bit 34 - UINT32 Reserved4:1; // bit 35 - UINT32 DriverTypeA:1; // bit 36 - UINT32 DriverTypeC:1; // bit 37 - UINT32 DriverTypeD:1; // bit 38 - UINT32 DriverType4:1; // bit 39 - UINT32 TimerCount:4; // bit 40:43 - UINT32 Reserved5:1; // bit 44 - UINT32 TuningSDR50:1; // bit 45 - UINT32 RetuningMod:2; // bit 46:47 - UINT32 ClkMultiplier:8; // bit 48:55 - UINT32 Reserved6:7; // bit 56:62 - UINT32 Hs400:1; // bit 63 -} EMMC_HC_SLOT_CAP; - -#pragma pack() - -/** - Software reset the specified EMMC host controller and enable all interrupts. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The software reset executes successfully. - @retval Others The software reset fails. - -**/ -EFI_STATUS -EmmcPeimHcReset ( - IN UINTN Bar - ); - -/** - Set all interrupt status bits in Normal and Error Interrupt Status Enable - register. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The operation executes successfully. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimHcEnableInterrupt ( - IN UINTN Bar - ); - -/** - Get the capability data from the specified slot. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[out] Capability The buffer to store the capability data. - - @retval EFI_SUCCESS The operation executes successfully. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimHcGetCapability ( - IN UINTN Bar, - OUT EMMC_HC_SLOT_CAP *Capability - ); - -/** - Detect whether there is a EMMC card attached at the specified EMMC host controller - slot. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS There is a EMMC card attached. - @retval EFI_NO_MEDIA There is not a EMMC card attached. - @retval Others The detection fails. - -**/ -EFI_STATUS -EmmcPeimHcCardDetect ( - IN UINTN Bar - ); - -/** - Initial EMMC host controller with lowest clock frequency, max power and max timeout value - at initialization. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The host controller is initialized successfully. - @retval Others The host controller isn't initialized successfully. - -**/ -EFI_STATUS -EmmcPeimHcInitHost ( - IN UINTN Bar - ); - -/** - Send command SWITCH to the EMMC device to switch the mode of operation of the - selected Device or modifies the EXT_CSD registers. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Access The access mode of SWTICH command. - @param[in] Index The offset of the field to be access. - @param[in] Value The value to be set to the specified field of EXT_CSD register. - @param[in] CmdSet The value of CmdSet field of EXT_CSD register. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSwitch ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT8 Access, - IN UINT8 Index, - IN UINT8 Value, - IN UINT8 CmdSet - ); - -/** - Send command SET_BLOCK_COUNT to the addressed EMMC device to set the number of - blocks for the following block read/write cmd. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] BlockCount The number of the logical block to access. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimSetBlkCount ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN UINT16 BlockCount - ); - -/** - Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed EMMC device - to read/write the specified number of blocks. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - @param[in] Lba The logical block address of starting access. - @param[in] BlockSize The block size of specified EMMC device partition. - @param[in] Buffer The pointer to the transfer buffer. - @param[in] BufferSize The size of transfer buffer. - @param[in] IsRead Boolean to show the operation direction. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -EmmcPeimRwMultiBlocks ( - IN EMMC_PEIM_HC_SLOT *Slot, - IN EFI_LBA Lba, - IN UINT32 BlockSize, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead - ); - -/** - Execute EMMC device identification procedure. - - Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details. - - @param[in] Slot The slot number of the Emmc card to send the command to. - - @retval EFI_SUCCESS There is a EMMC card. - @retval Others There is not a EMMC card. - -**/ -EFI_STATUS -EmmcPeimIdentification ( - IN EMMC_PEIM_HC_SLOT *Slot - ); - -/** - Free the resource used by the TRB. - - @param[in] Trb The pointer to the EMMC_TRB instance. - -**/ -VOID -EmmcPeimFreeTrb ( - IN EMMC_TRB *Trb - ); - -#endif - diff --git a/MdeModulePkg/Bus/Sd/EmmcDxe/ComponentName.c b/MdeModulePkg/Bus/Sd/EmmcDxe/ComponentName.c deleted file mode 100644 index c6545b658a..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcDxe/ComponentName.c +++ /dev/null @@ -1,242 +0,0 @@ -/** @file - UEFI Component Name(2) protocol implementation for EmmcDxe driver. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EmmcDxe.h" - -// -// Driver name table -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mEmmcDxeDriverNameTable[] = { - { "eng;en", L"Edkii Emmc Device Driver" }, - { NULL , NULL } -}; - -// -// Controller name table -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mEmmcDxeControllerNameTable[] = { - { "eng;en", L"Edkii Emmc Host Controller" }, - { NULL , NULL } -}; - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEmmcDxeComponentName = { - EmmcDxeComponentNameGetDriverName, - EmmcDxeComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmmcDxeComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmmcDxeComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmmcDxeComponentNameGetControllerName, - "en" -}; - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -EmmcDxeComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mEmmcDxeDriverNameTable, - DriverName, - (BOOLEAN)(This == &gEmmcDxeComponentName) - ); - -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -EmmcDxeComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EMMC_DEVICE *Device; - EMMC_PARTITION *Partition; - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - - // - // Make sure this driver is currently managing ControllHandle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gEmmcDxeDriverBinding.DriverBindingHandle, - &gEfiSdMmcPassThruProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - ControllerNameTable = mEmmcDxeControllerNameTable; - if (ChildHandle != NULL) { - Status = EfiTestChildHandle ( - ControllerHandle, - ChildHandle, - &gEfiSdMmcPassThruProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Get the child context - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo, - gEmmcDxeDriverBinding.DriverBindingHandle, - ChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Partition = EMMC_PARTITION_DATA_FROM_BLKIO (BlockIo); - Device = Partition->Device; - ControllerNameTable = Device->ControllerNameTable; - } - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - ControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gEmmcDxeComponentName) - ); -} - diff --git a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.c b/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.c deleted file mode 100644 index c432d26801..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.c +++ /dev/null @@ -1,2016 +0,0 @@ -/** @file - The helper functions for BlockIo and BlockIo2 protocol. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EmmcDxe.h" - -/** - Nonblocking I/O callback funtion when the event is signaled. - - @param[in] Event The Event this notify function registered to. - @param[in] Context Pointer to the context data registered to the - Event. - -**/ -VOID -EFIAPI -AsyncIoCallback ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EMMC_REQUEST *Request; - EFI_STATUS Status; - - Status = gBS->CloseEvent (Event); - if (EFI_ERROR (Status)) { - return; - } - - Request = (EMMC_REQUEST *) Context; - - DEBUG_CODE_BEGIN (); - DEBUG ((EFI_D_INFO, "Emmc Async Request: CmdIndex[%d] Arg[%08x] %r\n", - Request->SdMmcCmdBlk.CommandIndex, Request->SdMmcCmdBlk.CommandArgument, - Request->Packet.TransactionStatus)); - DEBUG_CODE_END (); - - if (EFI_ERROR (Request->Packet.TransactionStatus)) { - Request->Token->TransactionStatus = Request->Packet.TransactionStatus; - } - - RemoveEntryList (&Request->Link); - - if (Request->IsEnd) { - gBS->SignalEvent (Request->Token->Event); - } - - FreePool (Request); -} - -/** - Send command SELECT to the device to select/deselect the device. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[in] Rca The relative device address to use. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcSelect ( - IN EMMC_DEVICE *Device, - IN UINT16 Rca - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = EMMC_SELECT_DESELECT_CARD; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - - return Status; -} - -/** - Send command SEND_STATUS to the device to get device status. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] DevStatus The buffer to store the device status. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcSendStatus ( - IN EMMC_DEVICE *Device, - IN UINT16 Rca, - OUT UINT32 *DevStatus - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = EMMC_SEND_STATUS; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - if (!EFI_ERROR (Status)) { - CopyMem (DevStatus, &SdMmcStatusBlk.Resp0, sizeof (UINT32)); - } - - return Status; -} - -/** - Send command SEND_CSD to the device to get the CSD register data. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] Csd The buffer to store the EMMC_CSD register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcGetCsd ( - IN EMMC_DEVICE *Device, - IN UINT16 Rca, - OUT EMMC_CSD *Csd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - ZeroMem (Csd, sizeof (EMMC_CSD)); - - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = EMMC_SEND_CSD; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2; - SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - if (!EFI_ERROR (Status)) { - // - // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. - // - CopyMem (((UINT8*)Csd) + 1, &SdMmcStatusBlk.Resp0, sizeof (EMMC_CSD) - 1); - } - - return Status; -} - -/** - Send command SEND_CID to the device to get the CID register data. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] Cid The buffer to store the EMMC_CID register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcGetCid ( - IN EMMC_DEVICE *Device, - IN UINT16 Rca, - OUT EMMC_CID *Cid - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - ZeroMem (Cid, sizeof (EMMC_CID)); - - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = EMMC_SEND_CID; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2; - SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - if (!EFI_ERROR (Status)) { - // - // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. - // - CopyMem (((UINT8*)Cid) + 1, &SdMmcStatusBlk.Resp0, sizeof (EMMC_CID) - 1); - } - - return Status; -} - -/** - Send command SEND_EXT_CSD to the device to get the EXT_CSD register data. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[out] ExtCsd The buffer to store the EXT_CSD register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcGetExtCsd ( - IN EMMC_DEVICE *Device, - OUT EMMC_EXT_CSD *ExtCsd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - ZeroMem (ExtCsd, sizeof (EMMC_EXT_CSD)); - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = EMMC_SEND_EXT_CSD; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - SdMmcCmdBlk.CommandArgument = 0x00000000; - Packet.InDataBuffer = ExtCsd; - Packet.InTransferLength = sizeof (EMMC_EXT_CSD); - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - - return Status; -} - -/** - Set the specified EXT_CSD register field through sync or async I/O request. - - @param[in] Partition A pointer to the EMMC_PARTITION instance. - @param[in] Offset The offset of the specified field in EXT_CSD register. - @param[in] Value The byte value written to the field specified by Offset. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcSetExtCsd ( - IN EMMC_PARTITION *Partition, - IN UINT8 Offset, - IN UINT8 Value, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EMMC_DEVICE *Device; - EMMC_REQUEST *SetExtCsdReq; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - UINT32 CommandArgument; - EFI_TPL OldTpl; - - SetExtCsdReq = NULL; - - Device = Partition->Device; - PassThru = Device->Private->PassThru; - - SetExtCsdReq = AllocateZeroPool (sizeof (EMMC_REQUEST)); - if (SetExtCsdReq == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - SetExtCsdReq->Signature = EMMC_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Partition->Queue, &SetExtCsdReq->Link); - gBS->RestoreTPL (OldTpl); - SetExtCsdReq->Packet.SdMmcCmdBlk = &SetExtCsdReq->SdMmcCmdBlk; - SetExtCsdReq->Packet.SdMmcStatusBlk = &SetExtCsdReq->SdMmcStatusBlk; - SetExtCsdReq->Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - SetExtCsdReq->SdMmcCmdBlk.CommandIndex = EMMC_SWITCH; - SetExtCsdReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SetExtCsdReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b; - // - // Write the Value to the field specified by Offset. - // - CommandArgument = (Value << 8) | (Offset << 16) | BIT24 | BIT25; - SetExtCsdReq->SdMmcCmdBlk.CommandArgument = CommandArgument; - - SetExtCsdReq->IsEnd = IsEnd; - SetExtCsdReq->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - SetExtCsdReq, - &SetExtCsdReq->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - SetExtCsdReq->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &SetExtCsdReq->Packet, SetExtCsdReq->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (SetExtCsdReq != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&SetExtCsdReq->Link); - gBS->RestoreTPL (OldTpl); - if (SetExtCsdReq->Event != NULL) { - gBS->CloseEvent (SetExtCsdReq->Event); - } - FreePool (SetExtCsdReq); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (SetExtCsdReq != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&SetExtCsdReq->Link); - gBS->RestoreTPL (OldTpl); - FreePool (SetExtCsdReq); - } - } - - return Status; -} - -/** - Set the number of blocks for a block read/write cmd through sync or async I/O request. - - @param[in] Partition A pointer to the EMMC_PARTITION instance. - @param[in] BlockNum The number of blocks for transfer. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcSetBlkCount ( - IN EMMC_PARTITION *Partition, - IN UINT16 BlockNum, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EMMC_DEVICE *Device; - EMMC_REQUEST *SetBlkCntReq; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_TPL OldTpl; - - SetBlkCntReq = NULL; - - Device = Partition->Device; - PassThru = Device->Private->PassThru; - - SetBlkCntReq = AllocateZeroPool (sizeof (EMMC_REQUEST)); - if (SetBlkCntReq == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - SetBlkCntReq->Signature = EMMC_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Partition->Queue, &SetBlkCntReq->Link); - gBS->RestoreTPL (OldTpl); - SetBlkCntReq->Packet.SdMmcCmdBlk = &SetBlkCntReq->SdMmcCmdBlk; - SetBlkCntReq->Packet.SdMmcStatusBlk = &SetBlkCntReq->SdMmcStatusBlk; - SetBlkCntReq->Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - SetBlkCntReq->SdMmcCmdBlk.CommandIndex = EMMC_SET_BLOCK_COUNT; - SetBlkCntReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SetBlkCntReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - SetBlkCntReq->SdMmcCmdBlk.CommandArgument = BlockNum; - - SetBlkCntReq->IsEnd = IsEnd; - SetBlkCntReq->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - SetBlkCntReq, - &SetBlkCntReq->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - SetBlkCntReq->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &SetBlkCntReq->Packet, SetBlkCntReq->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (SetBlkCntReq != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&SetBlkCntReq->Link); - gBS->RestoreTPL (OldTpl); - if (SetBlkCntReq->Event != NULL) { - gBS->CloseEvent (SetBlkCntReq->Event); - } - FreePool (SetBlkCntReq); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (SetBlkCntReq != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&SetBlkCntReq->Link); - gBS->RestoreTPL (OldTpl); - FreePool (SetBlkCntReq); - } - } - - return Status; -} - -/** - Read blocks through security protocol cmds with the way of sync or async I/O request. - - @param[in] Partition A pointer to the EMMC_PARTITION instance. - @param[in] SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param[in] SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param[in] PayloadBufferSize Size in bytes of the payload data buffer. - @param[out] PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param[in] IsRead Indicates it is a read or write operation. - @param[in] Timeout The timeout value, in 100ns units. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcProtocolInOut ( - IN EMMC_PARTITION *Partition, - IN UINT8 SecurityProtocol, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - IN BOOLEAN IsRead, - IN UINT64 Timeout, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EMMC_DEVICE *Device; - EMMC_REQUEST *ProtocolReq; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_TPL OldTpl; - - ProtocolReq = NULL; - - Device = Partition->Device; - PassThru = Device->Private->PassThru; - - ProtocolReq = AllocateZeroPool (sizeof (EMMC_REQUEST)); - if (ProtocolReq == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - ProtocolReq->Signature = EMMC_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Partition->Queue, &ProtocolReq->Link); - gBS->RestoreTPL (OldTpl); - ProtocolReq->Packet.SdMmcCmdBlk = &ProtocolReq->SdMmcCmdBlk; - ProtocolReq->Packet.SdMmcStatusBlk = &ProtocolReq->SdMmcStatusBlk; - - if (IsRead) { - ProtocolReq->Packet.InDataBuffer = PayloadBuffer; - ProtocolReq->Packet.InTransferLength = (UINT32)PayloadBufferSize; - - ProtocolReq->SdMmcCmdBlk.CommandIndex = EMMC_PROTOCOL_RD; - ProtocolReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - ProtocolReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - } else { - ProtocolReq->Packet.OutDataBuffer = PayloadBuffer; - ProtocolReq->Packet.OutTransferLength = (UINT32)PayloadBufferSize; - - ProtocolReq->SdMmcCmdBlk.CommandIndex = EMMC_PROTOCOL_WR; - ProtocolReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - ProtocolReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - } - - ProtocolReq->SdMmcCmdBlk.CommandArgument = (SecurityProtocol << 8) | (SecurityProtocolSpecificData << 16); - // - // Convert to 1 microsecond unit. - // - ProtocolReq->Packet.Timeout = DivU64x32 (Timeout, 10) + 1; - - ProtocolReq->IsEnd = IsEnd; - ProtocolReq->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - ProtocolReq, - &ProtocolReq->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - ProtocolReq->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &ProtocolReq->Packet, ProtocolReq->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (ProtocolReq != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&ProtocolReq->Link); - gBS->RestoreTPL (OldTpl); - if (ProtocolReq->Event != NULL) { - gBS->CloseEvent (ProtocolReq->Event); - } - FreePool (ProtocolReq); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (ProtocolReq != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&ProtocolReq->Link); - gBS->RestoreTPL (OldTpl); - FreePool (ProtocolReq); - } - } - - return Status; -} - -/** - Read/write multiple blocks through sync or async I/O request. - - @param[in] Partition A pointer to the EMMC_PARTITION instance. - @param[in] Lba The starting logical block address to be read/written. - The caller is responsible for reading/writing to only - legitimate locations. - @param[in] Buffer A pointer to the destination/source buffer for the data. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] IsRead Indicates it is a read or write operation. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcRwMultiBlocks ( - IN EMMC_PARTITION *Partition, - IN EFI_LBA Lba, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EMMC_DEVICE *Device; - EMMC_REQUEST *RwMultiBlkReq; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_TPL OldTpl; - - RwMultiBlkReq = NULL; - - Device = Partition->Device; - PassThru = Device->Private->PassThru; - - RwMultiBlkReq = AllocateZeroPool (sizeof (EMMC_REQUEST)); - if (RwMultiBlkReq == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - RwMultiBlkReq->Signature = EMMC_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Partition->Queue, &RwMultiBlkReq->Link); - gBS->RestoreTPL (OldTpl); - RwMultiBlkReq->Packet.SdMmcCmdBlk = &RwMultiBlkReq->SdMmcCmdBlk; - RwMultiBlkReq->Packet.SdMmcStatusBlk = &RwMultiBlkReq->SdMmcStatusBlk; - // - // Calculate timeout value through the below formula. - // Timeout = (transfer size) / (2MB/s). - // Taking 2MB/s as divisor is because it's nearest to the eMMC lowest - // transfer speed (2.4MB/s). - // Refer to eMMC 5.0 spec section 6.9.1 for details. - // - RwMultiBlkReq->Packet.Timeout = (BufferSize / (2 * 1024 * 1024) + 1) * 1000 * 1000; - - if (IsRead) { - RwMultiBlkReq->Packet.InDataBuffer = Buffer; - RwMultiBlkReq->Packet.InTransferLength = (UINT32)BufferSize; - - RwMultiBlkReq->SdMmcCmdBlk.CommandIndex = EMMC_READ_MULTIPLE_BLOCK; - RwMultiBlkReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - RwMultiBlkReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - } else { - RwMultiBlkReq->Packet.OutDataBuffer = Buffer; - RwMultiBlkReq->Packet.OutTransferLength = (UINT32)BufferSize; - - RwMultiBlkReq->SdMmcCmdBlk.CommandIndex = EMMC_WRITE_MULTIPLE_BLOCK; - RwMultiBlkReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - RwMultiBlkReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - } - - if (Partition->Device->SectorAddressing) { - RwMultiBlkReq->SdMmcCmdBlk.CommandArgument = (UINT32)Lba; - } else { - RwMultiBlkReq->SdMmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (Lba, Partition->BlockMedia.BlockSize); - } - - RwMultiBlkReq->IsEnd = IsEnd; - RwMultiBlkReq->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - RwMultiBlkReq, - &RwMultiBlkReq->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - RwMultiBlkReq->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &RwMultiBlkReq->Packet, RwMultiBlkReq->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (RwMultiBlkReq != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&RwMultiBlkReq->Link); - gBS->RestoreTPL (OldTpl); - if (RwMultiBlkReq->Event != NULL) { - gBS->CloseEvent (RwMultiBlkReq->Event); - } - FreePool (RwMultiBlkReq); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (RwMultiBlkReq != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&RwMultiBlkReq->Link); - gBS->RestoreTPL (OldTpl); - FreePool (RwMultiBlkReq); - } - } - - return Status; -} - -/** - This function transfers data from/to EMMC device. - - @param[in] Partition A pointer to the EMMC_PARTITION instance. - @param[in] MediaId The media ID that the read/write request is for. - @param[in] Lba The starting logical block address to be read/written. - The caller is responsible for reading/writing to only - legitimate locations. - @param[in, out] Buffer A pointer to the destination/source buffer for the data. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] IsRead Indicates it is a read or write operation. - @param[in, out] Token A pointer to the token associated with the transaction. - - @retval EFI_SUCCESS The data was read/written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be read/written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read/write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EmmcReadWrite ( - IN EMMC_PARTITION *Partition, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead, - IN OUT EFI_BLOCK_IO2_TOKEN *Token - ) -{ - EFI_STATUS Status; - EMMC_DEVICE *Device; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN BlockNum; - UINTN IoAlign; - UINT8 PartitionConfig; - UINTN Remaining; - UINT32 MaxBlock; - BOOLEAN LastRw; - - Status = EFI_SUCCESS; - Device = Partition->Device; - Media = &Partition->BlockMedia; - LastRw = FALSE; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (!IsRead && Media->ReadOnly) { - return EFI_WRITE_PROTECTED; - } - - // - // Check parameters. - // - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - gBS->SignalEvent (Token->Event); - } - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - BlockNum = BufferSize / BlockSize; - if ((Lba + BlockNum - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if (IoAlign > 0 && (((UINTN) Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - } - // - // Check if needs to switch partition access. - // - PartitionConfig = Device->ExtCsd.PartitionConfig; - if ((PartitionConfig & 0x7) != Partition->PartitionType) { - PartitionConfig &= (UINT8)~0x7; - PartitionConfig |= Partition->PartitionType; - Status = EmmcSetExtCsd (Partition, OFFSET_OF (EMMC_EXT_CSD, PartitionConfig), PartitionConfig, Token, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - Device->ExtCsd.PartitionConfig = PartitionConfig; - } - // - // Start to execute data transfer. The max block number in single cmd is 65535 blocks. - // - Remaining = BlockNum; - MaxBlock = 0xFFFF; - - while (Remaining > 0) { - if (Remaining <= MaxBlock) { - BlockNum = Remaining; - LastRw = TRUE; - } else { - BlockNum = MaxBlock; - } - Status = EmmcSetBlkCount (Partition, (UINT16)BlockNum, Token, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - - BufferSize = BlockNum * BlockSize; - Status = EmmcRwMultiBlocks (Partition, Lba, Buffer, BufferSize, IsRead, Token, LastRw); - if (EFI_ERROR (Status)) { - return Status; - } - DEBUG ((EFI_D_INFO, "Emmc%a(): Part %d Lba 0x%x BlkNo 0x%x Event %p with %r\n", IsRead ? "Read " : "Write", Partition->PartitionType, Lba, BlockNum, (Token != NULL) ? Token->Event : NULL, Status)); - - Lba += BlockNum; - Buffer = (UINT8*)Buffer + BufferSize; - Remaining -= BlockNum; - } - - return Status; -} - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -EmmcReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EFI_STATUS Status; - EMMC_PARTITION *Partition; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - - Partition = EMMC_PARTITION_DATA_FROM_BLKIO (This); - - PassThru = Partition->Device->Private->PassThru; - Status = PassThru->ResetDevice (PassThru, Partition->Device->Slot); - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - } - - return Status; -} - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -EmmcReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - EMMC_PARTITION *Partition; - - Partition = EMMC_PARTITION_DATA_FROM_BLKIO (This); - - Status = EmmcReadWrite (Partition, MediaId, Lba, Buffer, BufferSize, TRUE, NULL); - return Status; -} - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -EmmcWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - EMMC_PARTITION *Partition; - - Partition = EMMC_PARTITION_DATA_FROM_BLKIO (This); - - Status = EmmcReadWrite (Partition, MediaId, Lba, Buffer, BufferSize, FALSE, NULL); - return Status; -} - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -EmmcFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -{ - // - // return directly - // - return EFI_SUCCESS; -} - -/** - Reset the Block Device. - - @param[in] This Indicates a pointer to the calling context. - @param[in] ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -EmmcResetEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EMMC_PARTITION *Partition; - LIST_ENTRY *Link; - LIST_ENTRY *NextLink; - EMMC_REQUEST *Request; - EFI_TPL OldTpl; - - Partition = EMMC_PARTITION_DATA_FROM_BLKIO2 (This); - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - for (Link = GetFirstNode (&Partition->Queue); - !IsNull (&Partition->Queue, Link); - Link = NextLink) { - NextLink = GetNextNode (&Partition->Queue, Link); - RemoveEntryList (Link); - - Request = EMMC_REQUEST_FROM_LINK (Link); - - gBS->CloseEvent (Request->Event); - Request->Token->TransactionStatus = EFI_ABORTED; - - if (Request->IsEnd) { - gBS->SignalEvent (Request->Token->Event); - } - - FreePool (Request); - } - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; -} - -/** - Read BufferSize bytes from Lba into Buffer. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId Id of the media, changes every time the media is replaced. - @param[in] Lba The starting Logical Block Address to read from. - @param[in, out] Token A pointer to the token associated with the transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[out] Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The read request was queued if Event is not NULL. - The data was read correctly from the device if - the Event is NULL. - @retval EFI_DEVICE_ERROR The device reported an error while performing - the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack - of resources. - -**/ -EFI_STATUS -EFIAPI -EmmcReadBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - EMMC_PARTITION *Partition; - - Partition = EMMC_PARTITION_DATA_FROM_BLKIO2 (This); - - Status = EmmcReadWrite (Partition, MediaId, Lba, Buffer, BufferSize, TRUE, Token); - return Status; -} - -/** - Write BufferSize bytes from Lba into Buffer. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] Lba The starting logical block address to be written. The - caller is responsible for writing to only legitimate - locations. - @param[in, out] Token A pointer to the token associated with the transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -EmmcWriteBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - EMMC_PARTITION *Partition; - - Partition = EMMC_PARTITION_DATA_FROM_BLKIO2 (This); - - Status = EmmcReadWrite (Partition, MediaId, Lba, Buffer, BufferSize, FALSE, Token); - return Status; -} - -/** - Flush the Block Device. - - @param[in] This Indicates a pointer to the calling context. - @param[in, out] Token A pointer to the token associated with the transaction. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -EmmcFlushBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN OUT EFI_BLOCK_IO2_TOKEN *Token - ) -{ - // - // Signal event and return directly. - // - if (Token != NULL && Token->Event != NULL) { - Token->TransactionStatus = EFI_SUCCESS; - gBS->SignalEvent (Token->Event); - } - - return EFI_SUCCESS; -} - -/** - Send a security protocol command to a device that receives data and/or the result - of one or more commands sent by SendData. - - The ReceiveData function sends a security protocol command to the given MediaId. - The security protocol command sent is defined by SecurityProtocolId and contains - the security protocol specific data SecurityProtocolSpecificData. The function - returns the data from the security protocol command in PayloadBuffer. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL IN command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. - - If the PayloadBufferSize is zero, the security protocol command is sent using the - Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBufferSize is too small to store the available data from the security - protocol command, the function shall copy PayloadBufferSize bytes into the - PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. - - If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, - the function shall return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function shall - return EFI_UNSUPPORTED. If there is no media in the device, the function returns - EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, - the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall - return EFI_SUCCESS. If the security protocol command completes with an error, the - function shall return EFI_DEVICE_ERROR. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId ID of the medium to receive data from. - @param[in] Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param[in] SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param[in] SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param[in] PayloadBufferSize Size in bytes of the payload data buffer. - @param[out] PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param[out] PayloadTransferSize A pointer to a buffer to store the size in bytes of the - data written to the payload data buffer. - @param[in] IsRead Indicates it is a read or write operation. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available - data from the device. The PayloadBuffer contains the truncated data. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and - PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -EmmcSecurityProtocolInOut ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - OUT UINTN *PayloadTransferSize, - IN BOOLEAN IsRead - ) -{ - EFI_STATUS Status; - EMMC_PARTITION *Partition; - EMMC_DEVICE *Device; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN BlockNum; - UINTN IoAlign; - UINTN Remaining; - UINT32 MaxBlock; - UINT8 PartitionConfig; - - Status = EFI_SUCCESS; - Partition = EMMC_PARTITION_DATA_FROM_SSP (This); - Device = Partition->Device; - Media = &Partition->BlockMedia; - - if (PayloadTransferSize != NULL) { - *PayloadTransferSize = 0; - } - - if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) { - return EFI_INVALID_PARAMETER; - } - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (PayloadBufferSize == 0) { - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((PayloadBufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - BlockNum = PayloadBufferSize / BlockSize; - - IoAlign = Media->IoAlign; - if (IoAlign > 0 && (((UINTN) PayloadBuffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - // - // Security protocol interface is synchronous transfer. - // Waiting for async I/O list to be empty before any operation. - // - while (!IsListEmpty (&Partition->Queue)); - - // - // Check if needs to switch partition access. - // - PartitionConfig = Device->ExtCsd.PartitionConfig; - if ((PartitionConfig & 0x7) != Partition->PartitionType) { - PartitionConfig &= (UINT8)~0x7; - PartitionConfig |= Partition->PartitionType; - Status = EmmcSetExtCsd (Partition, OFFSET_OF (EMMC_EXT_CSD, PartitionConfig), PartitionConfig, NULL, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - Device->ExtCsd.PartitionConfig = PartitionConfig; - } - // - // Start to execute data transfer. The max block number in single cmd is 65535 blocks. - // - Remaining = BlockNum; - MaxBlock = 0xFFFF; - - while (Remaining > 0) { - if (Remaining <= MaxBlock) { - BlockNum = Remaining; - } else { - BlockNum = MaxBlock; - } - - Status = EmmcSetBlkCount (Partition, (UINT16)BlockNum, NULL, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - - PayloadBufferSize = BlockNum * BlockSize; - Status = EmmcProtocolInOut (Partition, SecurityProtocolId, SecurityProtocolSpecificData, PayloadBufferSize, PayloadBuffer, IsRead, Timeout, NULL, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - - PayloadBuffer = (UINT8*)PayloadBuffer + PayloadBufferSize; - Remaining -= BlockNum; - if (PayloadTransferSize != NULL) { - *PayloadTransferSize += PayloadBufferSize; - } - } - - return Status; -} - -/** - Send a security protocol command to a device that receives data and/or the result - of one or more commands sent by SendData. - - The ReceiveData function sends a security protocol command to the given MediaId. - The security protocol command sent is defined by SecurityProtocolId and contains - the security protocol specific data SecurityProtocolSpecificData. The function - returns the data from the security protocol command in PayloadBuffer. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL IN command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. - - If the PayloadBufferSize is zero, the security protocol command is sent using the - Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBufferSize is too small to store the available data from the security - protocol command, the function shall copy PayloadBufferSize bytes into the - PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. - - If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, - the function shall return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function shall - return EFI_UNSUPPORTED. If there is no media in the device, the function returns - EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, - the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall - return EFI_SUCCESS. If the security protocol command completes with an error, the - function shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the - data written to the payload data buffer. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available - data from the device. The PayloadBuffer contains the truncated data. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and - PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -EmmcSecurityProtocolIn ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - OUT UINTN *PayloadTransferSize - ) -{ - EFI_STATUS Status; - - if ((PayloadTransferSize == NULL) && PayloadBufferSize != 0) { - return EFI_INVALID_PARAMETER; - } - - Status = EmmcSecurityProtocolInOut ( - This, - MediaId, - Timeout, - SecurityProtocolId, - SecurityProtocolSpecificData, - PayloadBufferSize, - PayloadBuffer, - PayloadTransferSize, - TRUE - ); - - return Status; -} - -/** - Send a security protocol command to a device. - - The SendData function sends a security protocol command containing the payload - PayloadBuffer to the given MediaId. The security protocol command sent is - defined by SecurityProtocolId and contains the security protocol specific data - SecurityProtocolSpecificData. If the underlying protocol command requires a - specific padding for the command payload, the SendData function shall add padding - bytes to the command payload to satisfy the padding requirements. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL OUT command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. If the PayloadBufferSize is zero, the security protocol command is - sent using the Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall - return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function - shall return EFI_UNSUPPORTED. If there is no media in the device, the function - returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the - device, the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall return - EFI_SUCCESS. If the security protocol command completes with an error, the function - shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -EmmcSecurityProtocolOut ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - IN VOID *PayloadBuffer - ) -{ - EFI_STATUS Status; - - Status = EmmcSecurityProtocolInOut ( - This, - MediaId, - Timeout, - SecurityProtocolId, - SecurityProtocolSpecificData, - PayloadBufferSize, - PayloadBuffer, - NULL, - FALSE - ); - - return Status; -} - -/** - Set the erase start address through sync or async I/O request. - - @param[in] Partition A pointer to the EMMC_PARTITION instance. - @param[in] StartLba The starting logical block address to be erased. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcEraseBlockStart ( - IN EMMC_PARTITION *Partition, - IN EFI_LBA StartLba, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EMMC_DEVICE *Device; - EMMC_REQUEST *EraseBlockStart; - EFI_TPL OldTpl; - - EraseBlockStart = NULL; - - Device = Partition->Device; - PassThru = Device->Private->PassThru; - - EraseBlockStart = AllocateZeroPool (sizeof (EMMC_REQUEST)); - if (EraseBlockStart == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - EraseBlockStart->Signature = EMMC_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Partition->Queue, &EraseBlockStart->Link); - gBS->RestoreTPL (OldTpl); - EraseBlockStart->Packet.SdMmcCmdBlk = &EraseBlockStart->SdMmcCmdBlk; - EraseBlockStart->Packet.SdMmcStatusBlk = &EraseBlockStart->SdMmcStatusBlk; - EraseBlockStart->Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - EraseBlockStart->SdMmcCmdBlk.CommandIndex = EMMC_ERASE_GROUP_START; - EraseBlockStart->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - EraseBlockStart->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - - if (Device->SectorAddressing) { - EraseBlockStart->SdMmcCmdBlk.CommandArgument = (UINT32)StartLba; - } else { - EraseBlockStart->SdMmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (StartLba, Partition->BlockMedia.BlockSize); - } - - EraseBlockStart->IsEnd = IsEnd; - EraseBlockStart->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - EraseBlockStart, - &EraseBlockStart->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - EraseBlockStart->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &EraseBlockStart->Packet, EraseBlockStart->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (EraseBlockStart != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlockStart->Link); - gBS->RestoreTPL (OldTpl); - if (EraseBlockStart->Event != NULL) { - gBS->CloseEvent (EraseBlockStart->Event); - } - FreePool (EraseBlockStart); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (EraseBlockStart != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlockStart->Link); - gBS->RestoreTPL (OldTpl); - FreePool (EraseBlockStart); - } - } - - return Status; -} - -/** - Set the erase end address through sync or async I/O request. - - @param[in] Partition A pointer to the EMMC_PARTITION instance. - @param[in] EndLba The ending logical block address to be erased. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcEraseBlockEnd ( - IN EMMC_PARTITION *Partition, - IN EFI_LBA EndLba, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EMMC_DEVICE *Device; - EMMC_REQUEST *EraseBlockEnd; - EFI_TPL OldTpl; - - EraseBlockEnd = NULL; - - Device = Partition->Device; - PassThru = Device->Private->PassThru; - - EraseBlockEnd = AllocateZeroPool (sizeof (EMMC_REQUEST)); - if (EraseBlockEnd == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - EraseBlockEnd->Signature = EMMC_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Partition->Queue, &EraseBlockEnd->Link); - gBS->RestoreTPL (OldTpl); - EraseBlockEnd->Packet.SdMmcCmdBlk = &EraseBlockEnd->SdMmcCmdBlk; - EraseBlockEnd->Packet.SdMmcStatusBlk = &EraseBlockEnd->SdMmcStatusBlk; - EraseBlockEnd->Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - EraseBlockEnd->SdMmcCmdBlk.CommandIndex = EMMC_ERASE_GROUP_END; - EraseBlockEnd->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - EraseBlockEnd->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - - if (Device->SectorAddressing) { - EraseBlockEnd->SdMmcCmdBlk.CommandArgument = (UINT32)EndLba; - } else { - EraseBlockEnd->SdMmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (EndLba, Partition->BlockMedia.BlockSize); - } - - EraseBlockEnd->IsEnd = IsEnd; - EraseBlockEnd->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - EraseBlockEnd, - &EraseBlockEnd->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - EraseBlockEnd->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &EraseBlockEnd->Packet, EraseBlockEnd->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (EraseBlockEnd != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlockEnd->Link); - gBS->RestoreTPL (OldTpl); - if (EraseBlockEnd->Event != NULL) { - gBS->CloseEvent (EraseBlockEnd->Event); - } - FreePool (EraseBlockEnd); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (EraseBlockEnd != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlockEnd->Link); - gBS->RestoreTPL (OldTpl); - FreePool (EraseBlockEnd); - } - } - - return Status; -} - -/** - Erase specified blocks through sync or async I/O request. - - @param[in] Partition A pointer to the EMMC_PARTITION instance. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcEraseBlock ( - IN EMMC_PARTITION *Partition, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EMMC_DEVICE *Device; - EMMC_REQUEST *EraseBlock; - EFI_TPL OldTpl; - - EraseBlock = NULL; - - Device = Partition->Device; - PassThru = Device->Private->PassThru; - - EraseBlock = AllocateZeroPool (sizeof (EMMC_REQUEST)); - if (EraseBlock == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - EraseBlock->Signature = EMMC_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Partition->Queue, &EraseBlock->Link); - gBS->RestoreTPL (OldTpl); - EraseBlock->Packet.SdMmcCmdBlk = &EraseBlock->SdMmcCmdBlk; - EraseBlock->Packet.SdMmcStatusBlk = &EraseBlock->SdMmcStatusBlk; - EraseBlock->Packet.Timeout = EMMC_GENERIC_TIMEOUT; - - EraseBlock->SdMmcCmdBlk.CommandIndex = EMMC_ERASE; - EraseBlock->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - EraseBlock->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b; - - EraseBlock->IsEnd = IsEnd; - EraseBlock->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - EraseBlock, - &EraseBlock->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - EraseBlock->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &EraseBlock->Packet, EraseBlock->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (EraseBlock != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlock->Link); - gBS->RestoreTPL (OldTpl); - if (EraseBlock->Event != NULL) { - gBS->CloseEvent (EraseBlock->Event); - } - FreePool (EraseBlock); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (EraseBlock != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlock->Link); - gBS->RestoreTPL (OldTpl); - FreePool (EraseBlock); - } - } - - return Status; -} - -/** - Erase a specified number of device blocks. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the erase request is for. - @param[in] Lba The starting logical block address to be - erased. The caller is responsible for erasing - only legitimate locations. - @param[in, out] Token A pointer to the token associated with the - transaction. - @param[in] Size The size in bytes to be erased. This must be - a multiple of the physical block size of the - device. - - @retval EFI_SUCCESS The erase request was queued if Event is not - NULL. The data was erased correctly to the - device if the Event is NULL.to the device. - @retval EFI_WRITE_PROTECTED The device cannot be erased due to write - protection. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the erase operation. - @retval EFI_INVALID_PARAMETER The erase request contains LBAs that are not - valid. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - -**/ -EFI_STATUS -EFIAPI -EmmcEraseBlocks ( - IN EFI_ERASE_BLOCK_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_ERASE_BLOCK_TOKEN *Token, - IN UINTN Size - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN BlockNum; - EFI_LBA LastLba; - UINT8 PartitionConfig; - EMMC_PARTITION *Partition; - EMMC_DEVICE *Device; - - Status = EFI_SUCCESS; - Partition = EMMC_PARTITION_DATA_FROM_ERASEBLK (This); - Device = Partition->Device; - Media = &Partition->BlockMedia; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Media->ReadOnly) { - return EFI_WRITE_PROTECTED; - } - - // - // Check parameters. - // - BlockSize = Media->BlockSize; - if ((Size % BlockSize) != 0) { - return EFI_INVALID_PARAMETER; - } - - BlockNum = Size / BlockSize; - if ((Lba + BlockNum - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - } - - LastLba = Lba + BlockNum - 1; - - // - // Check if needs to switch partition access. - // - PartitionConfig = Device->ExtCsd.PartitionConfig; - if ((PartitionConfig & 0x7) != Partition->PartitionType) { - PartitionConfig &= (UINT8)~0x7; - PartitionConfig |= Partition->PartitionType; - Status = EmmcSetExtCsd (Partition, OFFSET_OF (EMMC_EXT_CSD, PartitionConfig), PartitionConfig, (EFI_BLOCK_IO2_TOKEN*)Token, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - Device->ExtCsd.PartitionConfig = PartitionConfig; - } - - Status = EmmcEraseBlockStart (Partition, Lba, (EFI_BLOCK_IO2_TOKEN*)Token, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcEraseBlockEnd (Partition, LastLba, (EFI_BLOCK_IO2_TOKEN*)Token, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcEraseBlock (Partition, (EFI_BLOCK_IO2_TOKEN*)Token, TRUE); - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG ((EFI_D_ERROR, "EmmcEraseBlocks(): Lba 0x%x BlkNo 0x%x Event %p with %r\n", Lba, BlockNum, Token->Event, Status)); - - return Status; -} - diff --git a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.h b/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.h deleted file mode 100644 index c8a6c5cab4..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.h +++ /dev/null @@ -1,503 +0,0 @@ -/** @file - Header file for EmmcDxe Driver. - - This file defines common data structures, macro definitions and some module - internal function header files. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EMMC_BLOCK_IO_H_ -#define _EMMC_BLOCK_IO_H_ - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -EmmcReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -EmmcReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -EmmcWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -EmmcFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ); - -/** - Reset the Block Device. - - @param[in] This Indicates a pointer to the calling context. - @param[in] ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -EmmcResetEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId Id of the media, changes every time the media is replaced. - @param[in] Lba The starting Logical Block Address to read from. - @param[in, out] Token A pointer to the token associated with the transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[out] Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The read request was queued if Event is not NULL. - The data was read correctly from the device if - the Event is NULL. - @retval EFI_DEVICE_ERROR The device reported an error while performing - the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack - of resources. - -**/ -EFI_STATUS -EFIAPI -EmmcReadBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] Lba The starting logical block address to be written. The - caller is responsible for writing to only legitimate - locations. - @param[in, out] Token A pointer to the token associated with the transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -EmmcWriteBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - @param[in] This Indicates a pointer to the calling context. - @param[in, out] Token A pointer to the token associated with the transaction. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -EmmcFlushBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN OUT EFI_BLOCK_IO2_TOKEN *Token - ); - -/** - Send a security protocol command to a device that receives data and/or the result - of one or more commands sent by SendData. - - The ReceiveData function sends a security protocol command to the given MediaId. - The security protocol command sent is defined by SecurityProtocolId and contains - the security protocol specific data SecurityProtocolSpecificData. The function - returns the data from the security protocol command in PayloadBuffer. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL IN command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. - - If the PayloadBufferSize is zero, the security protocol command is sent using the - Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBufferSize is too small to store the available data from the security - protocol command, the function shall copy PayloadBufferSize bytes into the - PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. - - If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, - the function shall return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function shall - return EFI_UNSUPPORTED. If there is no media in the device, the function returns - EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, - the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall - return EFI_SUCCESS. If the security protocol command completes with an error, the - function shall return EFI_DEVICE_ERROR. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId ID of the medium to receive data from. - @param[in] Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param[in] SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param[in] SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param[in] PayloadBufferSize Size in bytes of the payload data buffer. - @param[out] PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param[out] PayloadTransferSize A pointer to a buffer to store the size in bytes of the - data written to the payload data buffer. - @param[in] IsRead Indicates it is a read or write operation. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available - data from the device. The PayloadBuffer contains the truncated data. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and - PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -EmmcSecurityProtocolInOut ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - OUT UINTN *PayloadTransferSize, - IN BOOLEAN IsRead - ); - -/** - Send a security protocol command to a device that receives data and/or the result - of one or more commands sent by SendData. - - The ReceiveData function sends a security protocol command to the given MediaId. - The security protocol command sent is defined by SecurityProtocolId and contains - the security protocol specific data SecurityProtocolSpecificData. The function - returns the data from the security protocol command in PayloadBuffer. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL IN command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. - - If the PayloadBufferSize is zero, the security protocol command is sent using the - Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBufferSize is too small to store the available data from the security - protocol command, the function shall copy PayloadBufferSize bytes into the - PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. - - If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, - the function shall return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function shall - return EFI_UNSUPPORTED. If there is no media in the device, the function returns - EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, - the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall - return EFI_SUCCESS. If the security protocol command completes with an error, the - function shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the - data written to the payload data buffer. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available - data from the device. The PayloadBuffer contains the truncated data. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and - PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -EmmcSecurityProtocolIn ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - OUT UINTN *PayloadTransferSize - ); - -/** - Send a security protocol command to a device. - - The SendData function sends a security protocol command containing the payload - PayloadBuffer to the given MediaId. The security protocol command sent is - defined by SecurityProtocolId and contains the security protocol specific data - SecurityProtocolSpecificData. If the underlying protocol command requires a - specific padding for the command payload, the SendData function shall add padding - bytes to the command payload to satisfy the padding requirements. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL OUT command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. If the PayloadBufferSize is zero, the security protocol command is - sent using the Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall - return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function - shall return EFI_UNSUPPORTED. If there is no media in the device, the function - returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the - device, the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall return - EFI_SUCCESS. If the security protocol command completes with an error, the function - shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -EmmcSecurityProtocolOut ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - IN VOID *PayloadBuffer - ); - -/** - Erase a specified number of device blocks. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the erase request is for. - @param[in] Lba The starting logical block address to be - erased. The caller is responsible for erasing - only legitimate locations. - @param[in, out] Token A pointer to the token associated with the - transaction. - @param[in] Size The size in bytes to be erased. This must be - a multiple of the physical block size of the - device. - - @retval EFI_SUCCESS The erase request was queued if Event is not - NULL. The data was erased correctly to the - device if the Event is NULL.to the device. - @retval EFI_WRITE_PROTECTED The device cannot be erased due to write - protection. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the erase operation. - @retval EFI_INVALID_PARAMETER The erase request contains LBAs that are not - valid. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - -**/ -EFI_STATUS -EFIAPI -EmmcEraseBlocks ( - IN EFI_ERASE_BLOCK_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_ERASE_BLOCK_TOKEN *Token, - IN UINTN Size - ); - -#endif - diff --git a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.c b/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.c deleted file mode 100644 index 5040882d62..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.c +++ /dev/null @@ -1,1198 +0,0 @@ -/** @file - The EmmcDxe driver is used to manage the EMMC device. - - It produces BlockIo, BlockIo2 and StorageSecurity protocols to allow upper layer - access the EMMC device. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EmmcDxe.h" - -// -// EmmcDxe Driver Binding Protocol Instance -// -EFI_DRIVER_BINDING_PROTOCOL gEmmcDxeDriverBinding = { - EmmcDxeDriverBindingSupported, - EmmcDxeDriverBindingStart, - EmmcDxeDriverBindingStop, - 0x10, - NULL, - NULL -}; - -// -// Template for Emmc Partitions. -// -EMMC_PARTITION mEmmcPartitionTemplate = { - EMMC_PARTITION_SIGNATURE, // Signature - FALSE, // Enable - EmmcPartitionUnknown, // PartitionType - NULL, // Handle - NULL, // DevicePath - { // BlockIo - EFI_BLOCK_IO_PROTOCOL_REVISION, - NULL, - EmmcReset, - EmmcReadBlocks, - EmmcWriteBlocks, - EmmcFlushBlocks - }, - { // BlockIo2 - NULL, - EmmcResetEx, - EmmcReadBlocksEx, - EmmcWriteBlocksEx, - EmmcFlushBlocksEx - }, - { // BlockMedia - 0, // MediaId - FALSE, // RemovableMedia - TRUE, // MediaPresent - FALSE, // LogicPartition - FALSE, // ReadOnly - FALSE, // WritingCache - 0x200, // BlockSize - 0, // IoAlign - 0 // LastBlock - }, - { // StorageSecurity - EmmcSecurityProtocolIn, - EmmcSecurityProtocolOut - }, - { // EraseBlock - EFI_ERASE_BLOCK_PROTOCOL_REVISION, - 1, - EmmcEraseBlocks - }, - { - NULL, - NULL - }, - NULL // Device -}; - -/** - Decode and print EMMC CSD Register content. - - @param[in] Csd Pointer to EMMC_CSD data structure. - - @retval EFI_SUCCESS The function completed successfully -**/ -EFI_STATUS -DumpCsd ( - IN EMMC_CSD *Csd - ) -{ - DEBUG((DEBUG_INFO, "== Dump Emmc Csd Register==\n")); - DEBUG((DEBUG_INFO, " CSD structure 0x%x\n", Csd->CsdStructure)); - DEBUG((DEBUG_INFO, " System specification version 0x%x\n", Csd->SpecVers)); - DEBUG((DEBUG_INFO, " Data read access-time 1 0x%x\n", Csd->Taac)); - DEBUG((DEBUG_INFO, " Data read access-time 2 0x%x\n", Csd->Nsac)); - DEBUG((DEBUG_INFO, " Max. bus clock frequency 0x%x\n", Csd->TranSpeed)); - DEBUG((DEBUG_INFO, " Device command classes 0x%x\n", Csd->Ccc)); - DEBUG((DEBUG_INFO, " Max. read data block length 0x%x\n", Csd->ReadBlLen)); - DEBUG((DEBUG_INFO, " Partial blocks for read allowed 0x%x\n", Csd->ReadBlPartial)); - DEBUG((DEBUG_INFO, " Write block misalignment 0x%x\n", Csd->WriteBlkMisalign)); - DEBUG((DEBUG_INFO, " Read block misalignment 0x%x\n", Csd->ReadBlkMisalign)); - DEBUG((DEBUG_INFO, " DSR implemented 0x%x\n", Csd->DsrImp)); - DEBUG((DEBUG_INFO, " Device size 0x%x\n", Csd->CSizeLow | (Csd->CSizeHigh << 2))); - DEBUG((DEBUG_INFO, " Max. read current @ VDD min 0x%x\n", Csd->VddRCurrMin)); - DEBUG((DEBUG_INFO, " Max. read current @ VDD max 0x%x\n", Csd->VddRCurrMax)); - DEBUG((DEBUG_INFO, " Max. write current @ VDD min 0x%x\n", Csd->VddWCurrMin)); - DEBUG((DEBUG_INFO, " Max. write current @ VDD max 0x%x\n", Csd->VddWCurrMax)); - DEBUG((DEBUG_INFO, " Device size multiplier 0x%x\n", Csd->CSizeMult)); - DEBUG((DEBUG_INFO, " Erase group size 0x%x\n", Csd->EraseGrpSize)); - DEBUG((DEBUG_INFO, " Erase group size multiplier 0x%x\n", Csd->EraseGrpMult)); - DEBUG((DEBUG_INFO, " Write protect group size 0x%x\n", Csd->WpGrpSize)); - DEBUG((DEBUG_INFO, " Write protect group enable 0x%x\n", Csd->WpGrpEnable)); - DEBUG((DEBUG_INFO, " Manufacturer default ECC 0x%x\n", Csd->DefaultEcc)); - DEBUG((DEBUG_INFO, " Write speed factor 0x%x\n", Csd->R2WFactor)); - DEBUG((DEBUG_INFO, " Max. write data block length 0x%x\n", Csd->WriteBlLen)); - DEBUG((DEBUG_INFO, " Partial blocks for write allowed 0x%x\n", Csd->WriteBlPartial)); - DEBUG((DEBUG_INFO, " Content protection application 0x%x\n", Csd->ContentProtApp)); - DEBUG((DEBUG_INFO, " File format group 0x%x\n", Csd->FileFormatGrp)); - DEBUG((DEBUG_INFO, " Copy flag (OTP) 0x%x\n", Csd->Copy)); - DEBUG((DEBUG_INFO, " Permanent write protection 0x%x\n", Csd->PermWriteProtect)); - DEBUG((DEBUG_INFO, " Temporary write protection 0x%x\n", Csd->TmpWriteProtect)); - DEBUG((DEBUG_INFO, " File format 0x%x\n", Csd->FileFormat)); - DEBUG((DEBUG_INFO, " ECC code 0x%x\n", Csd->Ecc)); - - return EFI_SUCCESS; -} - -/** - Decode and print EMMC EXT_CSD Register content. - - @param[in] ExtCsd Pointer to the EMMC_EXT_CSD data structure. - - @retval EFI_SUCCESS The function completed successfully -**/ -EFI_STATUS -DumpExtCsd ( - IN EMMC_EXT_CSD *ExtCsd - ) -{ - DEBUG((DEBUG_INFO, "==Dump Emmc ExtCsd Register==\n")); - DEBUG((DEBUG_INFO, " Supported Command Sets 0x%x\n", ExtCsd->CmdSet)); - DEBUG((DEBUG_INFO, " HPI features 0x%x\n", ExtCsd->HpiFeatures)); - DEBUG((DEBUG_INFO, " Background operations support 0x%x\n", ExtCsd->BkOpsSupport)); - DEBUG((DEBUG_INFO, " Background operations status 0x%x\n", ExtCsd->BkopsStatus)); - DEBUG((DEBUG_INFO, " Number of correctly programmed sectors 0x%x\n", *((UINT32*)&ExtCsd->CorrectlyPrgSectorsNum[0]))); - DEBUG((DEBUG_INFO, " Initialization time after partitioning 0x%x\n", ExtCsd->IniTimeoutAp)); - DEBUG((DEBUG_INFO, " TRIM Multiplier 0x%x\n", ExtCsd->TrimMult)); - DEBUG((DEBUG_INFO, " Secure Feature support 0x%x\n", ExtCsd->SecFeatureSupport)); - DEBUG((DEBUG_INFO, " Secure Erase Multiplier 0x%x\n", ExtCsd->SecEraseMult)); - DEBUG((DEBUG_INFO, " Secure TRIM Multiplier 0x%x\n", ExtCsd->SecTrimMult)); - DEBUG((DEBUG_INFO, " Boot information 0x%x\n", ExtCsd->BootInfo)); - DEBUG((DEBUG_INFO, " Boot partition size 0x%x\n", ExtCsd->BootSizeMult)); - DEBUG((DEBUG_INFO, " Access size 0x%x\n", ExtCsd->AccSize)); - DEBUG((DEBUG_INFO, " High-capacity erase unit size 0x%x\n", ExtCsd->HcEraseGrpSize)); - DEBUG((DEBUG_INFO, " High-capacity erase timeout 0x%x\n", ExtCsd->EraseTimeoutMult)); - DEBUG((DEBUG_INFO, " Reliable write sector count 0x%x\n", ExtCsd->RelWrSecC)); - DEBUG((DEBUG_INFO, " High-capacity write protect group size 0x%x\n", ExtCsd->HcWpGrpSize)); - DEBUG((DEBUG_INFO, " Sleep/awake timeout 0x%x\n", ExtCsd->SATimeout)); - DEBUG((DEBUG_INFO, " Sector Count 0x%x\n", *((UINT32*)&ExtCsd->SecCount[0]))); - DEBUG((DEBUG_INFO, " Partition switching timing 0x%x\n", ExtCsd->PartitionSwitchTime)); - DEBUG((DEBUG_INFO, " Out-of-interrupt busy timing 0x%x\n", ExtCsd->OutOfInterruptTime)); - DEBUG((DEBUG_INFO, " I/O Driver Strength 0x%x\n", ExtCsd->DriverStrength)); - DEBUG((DEBUG_INFO, " Device type 0x%x\n", ExtCsd->DeviceType)); - DEBUG((DEBUG_INFO, " CSD STRUCTURE 0x%x\n", ExtCsd->CsdStructure)); - DEBUG((DEBUG_INFO, " Extended CSD revision 0x%x\n", ExtCsd->ExtCsdRev)); - DEBUG((DEBUG_INFO, " Command set 0x%x\n", ExtCsd->CmdSet)); - DEBUG((DEBUG_INFO, " Command set revision 0x%x\n", ExtCsd->CmdSetRev)); - DEBUG((DEBUG_INFO, " Power class 0x%x\n", ExtCsd->PowerClass)); - DEBUG((DEBUG_INFO, " High-speed interface timing 0x%x\n", ExtCsd->HsTiming)); - DEBUG((DEBUG_INFO, " Bus width mode 0x%x\n", ExtCsd->BusWidth)); - DEBUG((DEBUG_INFO, " Erased memory content 0x%x\n", ExtCsd->ErasedMemCont)); - DEBUG((DEBUG_INFO, " Partition configuration 0x%x\n", ExtCsd->PartitionConfig)); - DEBUG((DEBUG_INFO, " Boot config protection 0x%x\n", ExtCsd->BootConfigProt)); - DEBUG((DEBUG_INFO, " Boot bus Conditions 0x%x\n", ExtCsd->BootBusConditions)); - DEBUG((DEBUG_INFO, " High-density erase group definition 0x%x\n", ExtCsd->EraseGroupDef)); - DEBUG((DEBUG_INFO, " Boot write protection status register 0x%x\n", ExtCsd->BootWpStatus)); - DEBUG((DEBUG_INFO, " Boot area write protection register 0x%x\n", ExtCsd->BootWp)); - DEBUG((DEBUG_INFO, " User area write protection register 0x%x\n", ExtCsd->UserWp)); - DEBUG((DEBUG_INFO, " FW configuration 0x%x\n", ExtCsd->FwConfig)); - DEBUG((DEBUG_INFO, " RPMB Size 0x%x\n", ExtCsd->RpmbSizeMult)); - DEBUG((DEBUG_INFO, " H/W reset function 0x%x\n", ExtCsd->RstFunction)); - DEBUG((DEBUG_INFO, " Partitioning Support 0x%x\n", ExtCsd->PartitioningSupport)); - DEBUG((DEBUG_INFO, " Max Enhanced Area Size 0x%02x%02x%02x\n", \ - ExtCsd->MaxEnhSizeMult[2], ExtCsd->MaxEnhSizeMult[1], ExtCsd->MaxEnhSizeMult[0])); - DEBUG((DEBUG_INFO, " Partitions attribute 0x%x\n", ExtCsd->PartitionsAttribute)); - DEBUG((DEBUG_INFO, " Partitioning Setting 0x%x\n", ExtCsd->PartitionSettingCompleted)); - DEBUG((DEBUG_INFO, " General Purpose Partition 1 Size 0x%02x%02x%02x\n", \ - ExtCsd->GpSizeMult[2], ExtCsd->GpSizeMult[1], ExtCsd->GpSizeMult[0])); - DEBUG((DEBUG_INFO, " General Purpose Partition 2 Size 0x%02x%02x%02x\n", \ - ExtCsd->GpSizeMult[5], ExtCsd->GpSizeMult[4], ExtCsd->GpSizeMult[3])); - DEBUG((DEBUG_INFO, " General Purpose Partition 3 Size 0x%02x%02x%02x\n", \ - ExtCsd->GpSizeMult[8], ExtCsd->GpSizeMult[7], ExtCsd->GpSizeMult[6])); - DEBUG((DEBUG_INFO, " General Purpose Partition 4 Size 0x%02x%02x%02x\n", \ - ExtCsd->GpSizeMult[11], ExtCsd->GpSizeMult[10], ExtCsd->GpSizeMult[9])); - DEBUG((DEBUG_INFO, " Enhanced User Data Area Size 0x%02x%02x%02x\n", \ - ExtCsd->EnhSizeMult[2], ExtCsd->EnhSizeMult[1], ExtCsd->EnhSizeMult[0])); - DEBUG((DEBUG_INFO, " Enhanced User Data Start Address 0x%x\n", *((UINT32*)&ExtCsd->EnhStartAddr[0]))); - DEBUG((DEBUG_INFO, " Bad Block Management mode 0x%x\n", ExtCsd->SecBadBlkMgmnt)); - DEBUG((DEBUG_INFO, " Native sector size 0x%x\n", ExtCsd->NativeSectorSize)); - DEBUG((DEBUG_INFO, " Sector size emulation 0x%x\n", ExtCsd->UseNativeSector)); - DEBUG((DEBUG_INFO, " Sector size 0x%x\n", ExtCsd->DataSectorSize)); - - return EFI_SUCCESS; -} - -/** - Get EMMC device model name. - - @param[in, out] Device The pointer to the EMMC_DEVICE data structure. - @param[in] Cid Pointer to EMMC_CID data structure. - - @retval EFI_SUCCESS The function completed successfully - -**/ -EFI_STATUS -GetEmmcModelName ( - IN OUT EMMC_DEVICE *Device, - IN EMMC_CID *Cid - ) -{ - CHAR8 String[EMMC_MODEL_NAME_MAX_LEN]; - - ZeroMem (String, sizeof (String)); - CopyMem (String, &Cid->OemId, sizeof (Cid->OemId)); - String[sizeof (Cid->OemId)] = ' '; - CopyMem (String + sizeof (Cid->OemId) + 1, Cid->ProductName, sizeof (Cid->ProductName)); - String[sizeof (Cid->OemId) + sizeof (Cid->ProductName)] = ' '; - CopyMem (String + sizeof (Cid->OemId) + sizeof (Cid->ProductName) + 1, Cid->ProductSerialNumber, sizeof (Cid->ProductSerialNumber)); - - AsciiStrToUnicodeStrS (String, Device->ModelName, sizeof (Device->ModelName) / sizeof (Device->ModelName[0])); - - return EFI_SUCCESS; -} - -/** - Discover all partitions in the EMMC device. - - @param[in] Device The pointer to the EMMC_DEVICE data structure. - - @retval EFI_SUCCESS All the partitions in the device are successfully enumerated. - @return Others Some error occurs when enumerating the partitions. - -**/ -EFI_STATUS -DiscoverAllPartitions ( - IN EMMC_DEVICE *Device - ) -{ - EFI_STATUS Status; - EMMC_PARTITION *Partition; - EMMC_CSD *Csd; - EMMC_CID *Cid; - EMMC_EXT_CSD *ExtCsd; - UINT8 Slot; - UINT64 Capacity; - UINT32 DevStatus; - UINT8 Index; - UINT32 SecCount; - UINT32 GpSizeMult; - - Slot = Device->Slot; - - Status = EmmcSendStatus (Device, Slot + 1, &DevStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Deselect the device to force it enter stby mode before getting CSD - // register content. - // Note here we don't judge return status as some EMMC devices return - // error but the state has been stby. - // - EmmcSelect (Device, 0); - - Status = EmmcSendStatus (Device, Slot + 1, &DevStatus); - if (EFI_ERROR (Status)) { - return Status; - } - - Csd = &Device->Csd; - Status = EmmcGetCsd (Device, Slot + 1, Csd); - if (EFI_ERROR (Status)) { - return Status; - } - DumpCsd (Csd); - - if ((Csd->CSizeLow | Csd->CSizeHigh << 2) == 0xFFF) { - Device->SectorAddressing = TRUE; - } else { - Device->SectorAddressing = FALSE; - } - - Cid = &Device->Cid; - Status = EmmcGetCid (Device, Slot + 1, Cid); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EmmcSelect (Device, Slot + 1); - if (EFI_ERROR (Status)) { - return Status; - } - - ExtCsd = &Device->ExtCsd; - Status = EmmcGetExtCsd (Device, ExtCsd); - if (EFI_ERROR (Status)) { - return Status; - } - DumpExtCsd (ExtCsd); - - if (ExtCsd->ExtCsdRev < 5) { - DEBUG ((EFI_D_ERROR, "The EMMC device version is too low, we don't support!!!\n")); - return EFI_UNSUPPORTED; - } - - if ((ExtCsd->PartitioningSupport & BIT0) != BIT0) { - DEBUG ((EFI_D_ERROR, "The EMMC device doesn't support Partition Feature!!!\n")); - return EFI_UNSUPPORTED; - } - - for (Index = 0; Index < EMMC_MAX_PARTITIONS; Index++) { - Partition = &Device->Partition[Index]; - CopyMem (Partition, &mEmmcPartitionTemplate, sizeof (EMMC_PARTITION)); - Partition->Device = Device; - InitializeListHead (&Partition->Queue); - Partition->BlockIo.Media = &Partition->BlockMedia; - Partition->BlockIo2.Media = &Partition->BlockMedia; - Partition->PartitionType = Index; - Partition->BlockMedia.IoAlign = Device->Private->PassThru->IoAlign; - Partition->BlockMedia.BlockSize = 0x200; - Partition->BlockMedia.LastBlock = 0x00; - Partition->BlockMedia.RemovableMedia = FALSE; - Partition->BlockMedia.MediaPresent = TRUE; - Partition->BlockMedia.LogicalPartition = FALSE; - - switch (Index) { - case EmmcPartitionUserData: - SecCount = *(UINT32*)&ExtCsd->SecCount; - Capacity = MultU64x32 ((UINT64) SecCount, 0x200); - break; - case EmmcPartitionBoot1: - case EmmcPartitionBoot2: - Capacity = ExtCsd->BootSizeMult * SIZE_128KB; - break; - case EmmcPartitionRPMB: - Capacity = ExtCsd->RpmbSizeMult * SIZE_128KB; - break; - case EmmcPartitionGP1: - GpSizeMult = (UINT32)(ExtCsd->GpSizeMult[0] | (ExtCsd->GpSizeMult[1] << 8) | (ExtCsd->GpSizeMult[2] << 16)); - Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB); - break; - case EmmcPartitionGP2: - GpSizeMult = (UINT32)(ExtCsd->GpSizeMult[3] | (ExtCsd->GpSizeMult[4] << 8) | (ExtCsd->GpSizeMult[5] << 16)); - Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB); - break; - case EmmcPartitionGP3: - GpSizeMult = (UINT32)(ExtCsd->GpSizeMult[6] | (ExtCsd->GpSizeMult[7] << 8) | (ExtCsd->GpSizeMult[8] << 16)); - Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB); - break; - case EmmcPartitionGP4: - GpSizeMult = (UINT32)(ExtCsd->GpSizeMult[9] | (ExtCsd->GpSizeMult[10] << 8) | (ExtCsd->GpSizeMult[11] << 16)); - Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB); - break; - default: - ASSERT (FALSE); - return EFI_INVALID_PARAMETER; - } - - if (Capacity != 0) { - Partition->Enable = TRUE; - Partition->BlockMedia.LastBlock = DivU64x32 (Capacity, Partition->BlockMedia.BlockSize) - 1; - } - - if ((ExtCsd->EraseGroupDef & BIT0) == 0) { - if (Csd->WriteBlLen < 9) { - Partition->EraseBlock.EraseLengthGranularity = 1; - } else { - Partition->EraseBlock.EraseLengthGranularity = (Csd->EraseGrpMult + 1) * (Csd->EraseGrpSize + 1) * (1 << (Csd->WriteBlLen - 9)); - } - } else { - Partition->EraseBlock.EraseLengthGranularity = 1024 * ExtCsd->HcEraseGrpSize; - } - } - - return EFI_SUCCESS; -} - -/** - Install BlkIo, BlkIo2 and Ssp protocols for the specified partition in the EMMC device. - - @param[in] Device The pointer to the EMMC_DEVICE data structure. - @param[in] Index The index of the partition. - - @retval EFI_SUCCESS The protocols are installed successfully. - @retval Others Some error occurs when installing the protocols. - -**/ -EFI_STATUS -InstallProtocolOnPartition ( - IN EMMC_DEVICE *Device, - IN UINT8 Index - ) -{ - EFI_STATUS Status; - EMMC_PARTITION *Partition; - CONTROLLER_DEVICE_PATH ControlNode; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - EFI_HANDLE DeviceHandle; - - // - // Build device path - // - ParentDevicePath = Device->DevicePath; - - ControlNode.Header.Type = HARDWARE_DEVICE_PATH; - ControlNode.Header.SubType = HW_CONTROLLER_DP; - SetDevicePathNodeLength (&ControlNode.Header, sizeof (CONTROLLER_DEVICE_PATH)); - ControlNode.ControllerNumber = Index; - - DevicePath = AppendDevicePathNode (ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&ControlNode); - if (DevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - DeviceHandle = NULL; - RemainingDevicePath = DevicePath; - Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle); - if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) { - Status = EFI_ALREADY_STARTED; - goto Error; - } - - Partition = &Device->Partition[Index]; - Partition->DevicePath = DevicePath; - if (Partition->Enable) { - // - // Install BlkIo/BlkIo2/Ssp for the specified partition - // - if (Partition->PartitionType != EmmcPartitionRPMB) { - Status = gBS->InstallMultipleProtocolInterfaces ( - &Partition->Handle, - &gEfiDevicePathProtocolGuid, - Partition->DevicePath, - &gEfiBlockIoProtocolGuid, - &Partition->BlockIo, - &gEfiBlockIo2ProtocolGuid, - &Partition->BlockIo2, - &gEfiEraseBlockProtocolGuid, - &Partition->EraseBlock, - NULL - ); - if (EFI_ERROR (Status)) { - goto Error; - } - - if (((Partition->PartitionType == EmmcPartitionUserData) || - (Partition->PartitionType == EmmcPartitionBoot1) || - (Partition->PartitionType == EmmcPartitionBoot2)) && - ((Device->Csd.Ccc & BIT10) != 0)) { - Status = gBS->InstallProtocolInterface ( - &Partition->Handle, - &gEfiStorageSecurityCommandProtocolGuid, - EFI_NATIVE_INTERFACE, - &Partition->StorageSecurity - ); - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - &Partition->Handle, - &gEfiDevicePathProtocolGuid, - Partition->DevicePath, - &gEfiBlockIoProtocolGuid, - &Partition->BlockIo, - &gEfiBlockIo2ProtocolGuid, - &Partition->BlockIo2, - &gEfiEraseBlockProtocolGuid, - &Partition->EraseBlock, - NULL - ); - goto Error; - } - } - - gBS->OpenProtocol ( - Device->Private->Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID **) &(Device->Private->PassThru), - Device->Private->DriverBindingHandle, - Partition->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - } - - } else { - Status = EFI_INVALID_PARAMETER; - } - -Error: - if (EFI_ERROR (Status) && (DevicePath != NULL)) { - FreePool (DevicePath); - } - - return Status; -} - -/** - Scan EMMC Bus to discover the device. - - @param[in] Private The EMMC driver private data structure. - @param[in] Slot The slot number to check device present. - @param[in] RemainingDevicePath The pointer to the remaining device path. - - @retval EFI_SUCCESS Successfully to discover the device and attach - SdMmcIoProtocol to it. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack - of resources. - @retval EFI_ALREADY_STARTED The device was discovered before. - @retval Others Fail to discover the device. - -**/ -EFI_STATUS -EFIAPI -DiscoverEmmcDevice ( - IN EMMC_DRIVER_PRIVATE_DATA *Private, - IN UINT8 Slot, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EMMC_DEVICE *Device; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - EFI_DEVICE_PATH_PROTOCOL *RemainingEmmcDevPath; - EFI_DEV_PATH *Node; - EFI_HANDLE DeviceHandle; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - UINT8 Index; - - Device = NULL; - DevicePath = NULL; - NewDevicePath = NULL; - RemainingDevicePath = NULL; - PassThru = Private->PassThru; - Device = &Private->Device[Slot]; - - // - // Build Device Path to check if the EMMC device present at the slot. - // - Status = PassThru->BuildDevicePath ( - PassThru, - Slot, - &DevicePath - ); - if (EFI_ERROR(Status)) { - return Status; - } - - if (DevicePath->SubType != MSG_EMMC_DP) { - Status = EFI_UNSUPPORTED; - goto Error; - } - - NewDevicePath = AppendDevicePathNode ( - Private->ParentDevicePath, - DevicePath - ); - if (NewDevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - DeviceHandle = NULL; - RemainingEmmcDevPath = NewDevicePath; - Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingEmmcDevPath, &DeviceHandle); - // - // The device path to the EMMC device doesn't exist. It means the corresponding device private data hasn't been initialized. - // - if (EFI_ERROR (Status) || (DeviceHandle == NULL) || !IsDevicePathEnd (RemainingEmmcDevPath)) { - Device->DevicePath = NewDevicePath; - Device->Slot = Slot; - Device->Private = Private; - // - // Expose user area in the Sd memory card to upper layer. - // - Status = DiscoverAllPartitions (Device); - if (EFI_ERROR(Status)) { - FreePool (NewDevicePath); - goto Error; - } - - Status = gBS->InstallProtocolInterface ( - &Device->Handle, - &gEfiDevicePathProtocolGuid, - EFI_NATIVE_INTERFACE, - Device->DevicePath - ); - if (EFI_ERROR(Status)) { - FreePool (NewDevicePath); - goto Error; - } - - Device->ControllerNameTable = NULL; - GetEmmcModelName (Device, &Device->Cid); - AddUnicodeString2 ( - "eng", - gEmmcDxeComponentName.SupportedLanguages, - &Device->ControllerNameTable, - Device->ModelName, - TRUE - ); - AddUnicodeString2 ( - "en", - gEmmcDxeComponentName.SupportedLanguages, - &Device->ControllerNameTable, - Device->ModelName, - FALSE - ); - } - - if (RemainingDevicePath == NULL) { - // - // Expose all partitions in the Emmc device to upper layer. - // - for (Index = 0; Index < EMMC_MAX_PARTITIONS; Index++) { - InstallProtocolOnPartition (Device, Index); - } - } else if (!IsDevicePathEnd (RemainingDevicePath)) { - // - // Enumerate the specified partition - // - Node = (EFI_DEV_PATH *) RemainingDevicePath; - if ((DevicePathType (&Node->DevPath) != HARDWARE_DEVICE_PATH) || - (DevicePathSubType (&Node->DevPath) != HW_CONTROLLER_DP) || - (DevicePathNodeLength (&Node->DevPath) != sizeof (CONTROLLER_DEVICE_PATH))) { - Status = EFI_INVALID_PARAMETER; - goto Error; - } - - Index = (UINT8)Node->Controller.ControllerNumber; - if (Index >= EMMC_MAX_PARTITIONS) { - Status = EFI_INVALID_PARAMETER; - goto Error; - } - - Status = InstallProtocolOnPartition (Device, Index); - } - -Error: - FreePool (DevicePath); - - return Status; -} - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -EmmcDxeDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - UINT8 Slot; - - // - // Test EFI_SD_MMC_PASS_THRU_PROTOCOL on the controller handle. - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID**) &PassThru, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Test RemainingDevicePath is valid or not. - // - if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) { - Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot); - if (EFI_ERROR (Status)) { - // - // Close the I/O Abstraction(s) used to perform the supported test - // - gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - Controller - ); - return Status; - } - } - - // - // Close the I/O Abstraction(s) used to perform the supported test - // - gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - // - // Open the EFI Device Path protocol needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - return Status; -} - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -EmmcDxeDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EMMC_DRIVER_PRIVATE_DATA *Private; - UINT8 Slot; - - Private = NULL; - PassThru = NULL; - Status = gBS->OpenProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID **) &PassThru, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) { - return Status; - } - - // - // Check EFI_ALREADY_STARTED to reuse the original EMMC_DRIVER_PRIVATE_DATA. - // - if (Status != EFI_ALREADY_STARTED) { - Private = AllocateZeroPool (sizeof (EMMC_DRIVER_PRIVATE_DATA)); - if (Private == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - Private->PassThru = PassThru; - Private->Controller = Controller; - Private->ParentDevicePath = ParentDevicePath; - Private->DriverBindingHandle = This->DriverBindingHandle; - - Status = gBS->InstallProtocolInterface ( - &Controller, - &gEfiCallerIdGuid, - EFI_NATIVE_INTERFACE, - Private - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - Status = gBS->OpenProtocol ( - Controller, - &gEfiCallerIdGuid, - (VOID **) &Private, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } - - if (RemainingDevicePath == NULL) { - Slot = 0xFF; - while (TRUE) { - Status = PassThru->GetNextSlot (PassThru, &Slot); - if (EFI_ERROR (Status)) { - // - // Cannot find more legal slots. - // - Status = EFI_SUCCESS; - break; - } - - Status = DiscoverEmmcDevice (Private, Slot, NULL); - if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { - break; - } - } - } else if (!IsDevicePathEnd (RemainingDevicePath)) { - Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot); - if (!EFI_ERROR (Status)) { - Status = DiscoverEmmcDevice (Private, Slot, NextDevicePathNode (RemainingDevicePath)); - } - } - -Error: - if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { - gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - if (Private != NULL) { - gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiCallerIdGuid, - Private, - NULL - ); - FreePool (Private); - } - } - return Status; -} - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -EmmcDxeDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_STATUS Status; - BOOLEAN AllChildrenStopped; - UINTN Index; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EMMC_DRIVER_PRIVATE_DATA *Private; - EMMC_DEVICE *Device; - EMMC_PARTITION *Partition; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_BLOCK_IO2_PROTOCOL *BlockIo2; - EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurity; - LIST_ENTRY *Link; - LIST_ENTRY *NextLink; - EMMC_REQUEST *Request; - - BlockIo = NULL; - BlockIo2 = NULL; - if (NumberOfChildren == 0) { - Status = gBS->OpenProtocol ( - Controller, - &gEfiCallerIdGuid, - (VOID **) &Private, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - for (Index = 0; Index < EMMC_MAX_DEVICES; Index++) { - Device = &Private->Device[Index]; - Status = gBS->OpenProtocol ( - Device->Handle, - &gEfiDevicePathProtocolGuid, - (VOID **) &DevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - continue; - } - ASSERT (DevicePath == Device->DevicePath); - gBS->UninstallProtocolInterface ( - Device->Handle, - &gEfiDevicePathProtocolGuid, - DevicePath - ); - FreePool (Device->DevicePath); - } - - gBS->UninstallProtocolInterface ( - Controller, - &gEfiCallerIdGuid, - Private - ); - gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - Controller - ); - FreePool (Private); - - return EFI_SUCCESS; - } - - AllChildrenStopped = TRUE; - - for (Index = 0; Index < NumberOfChildren; Index++) { - Status = gBS->OpenProtocol ( - ChildHandleBuffer[Index], - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - Status = gBS->OpenProtocol ( - ChildHandleBuffer[Index], - &gEfiBlockIo2ProtocolGuid, - (VOID **) &BlockIo2, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - continue; - } - } - - if (BlockIo != NULL) { - Partition = EMMC_PARTITION_DATA_FROM_BLKIO (BlockIo); - } else { - ASSERT (BlockIo2 != NULL); - Partition = EMMC_PARTITION_DATA_FROM_BLKIO2 (BlockIo2); - } - - for (Link = GetFirstNode (&Partition->Queue); - !IsNull (&Partition->Queue, Link); - Link = NextLink) { - NextLink = GetNextNode (&Partition->Queue, Link); - - RemoveEntryList (Link); - Request = EMMC_REQUEST_FROM_LINK (Link); - - gBS->CloseEvent (Request->Event); - Request->Token->TransactionStatus = EFI_ABORTED; - - if (Request->IsEnd) { - gBS->SignalEvent (Request->Token->Event); - } - - FreePool (Request); - } - - // - // Close the child handle - // - Status = gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - ChildHandleBuffer[Index] - ); - - Status = gBS->UninstallMultipleProtocolInterfaces ( - ChildHandleBuffer[Index], - &gEfiDevicePathProtocolGuid, - Partition->DevicePath, - &gEfiBlockIoProtocolGuid, - &Partition->BlockIo, - &gEfiBlockIo2ProtocolGuid, - &Partition->BlockIo2, - &gEfiEraseBlockProtocolGuid, - &Partition->EraseBlock, - NULL - ); - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - gBS->OpenProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID **)&Partition->Device->Private->PassThru, - This->DriverBindingHandle, - ChildHandleBuffer[Index], - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - continue; - } - - // - // If Storage Security Command Protocol is installed, then uninstall this protocol. - // - Status = gBS->OpenProtocol ( - ChildHandleBuffer[Index], - &gEfiStorageSecurityCommandProtocolGuid, - (VOID **) &StorageSecurity, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (!EFI_ERROR (Status)) { - Status = gBS->UninstallProtocolInterface ( - ChildHandleBuffer[Index], - &gEfiStorageSecurityCommandProtocolGuid, - &Partition->StorageSecurity - ); - if (EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID **) &Partition->Device->Private->PassThru, - This->DriverBindingHandle, - ChildHandleBuffer[Index], - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - AllChildrenStopped = FALSE; - continue; - } - } - - FreePool (Partition->DevicePath); - } - - if (!AllChildrenStopped) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - The user Entry Point for module EmmcDxe. The user code starts with this function. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval other Some errors occur when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -InitializeEmmcDxe ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - // - // Install driver model protocol(s). - // - Status = EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gEmmcDxeDriverBinding, - ImageHandle, - &gEmmcDxeComponentName, - &gEmmcDxeComponentName2 - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} - diff --git a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.h b/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.h deleted file mode 100644 index 0ae4eccac6..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.h +++ /dev/null @@ -1,500 +0,0 @@ -/** @file - Header file for EmmcDxe Driver. - - This file defines common data structures, macro definitions and some module - internal function header files. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EMMC_DXE_H_ -#define _EMMC_DXE_H_ - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "EmmcBlockIo.h" -// -// Global Variables -// -extern EFI_DRIVER_BINDING_PROTOCOL gEmmcDxeDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gEmmcDxeComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gEmmcDxeComponentName2; - -#define EMMC_PARTITION_SIGNATURE SIGNATURE_32 ('E', 'm', 'm', 'P') - -#define EMMC_PARTITION_DATA_FROM_BLKIO(a) \ - CR(a, EMMC_PARTITION, BlockIo, EMMC_PARTITION_SIGNATURE) - -#define EMMC_PARTITION_DATA_FROM_BLKIO2(a) \ - CR(a, EMMC_PARTITION, BlockIo2, EMMC_PARTITION_SIGNATURE) - -#define EMMC_PARTITION_DATA_FROM_SSP(a) \ - CR(a, EMMC_PARTITION, StorageSecurity, EMMC_PARTITION_SIGNATURE) - -#define EMMC_PARTITION_DATA_FROM_ERASEBLK(a) \ - CR(a, EMMC_PARTITION, EraseBlock, EMMC_PARTITION_SIGNATURE) - -// -// Take 2.5 seconds as generic time out value, 1 microsecond as unit. -// -#define EMMC_GENERIC_TIMEOUT 2500 * 1000 - -#define EMMC_REQUEST_SIGNATURE SIGNATURE_32 ('E', 'm', 'R', 'e') - -typedef struct _EMMC_DEVICE EMMC_DEVICE; -typedef struct _EMMC_DRIVER_PRIVATE_DATA EMMC_DRIVER_PRIVATE_DATA; - -// -// Asynchronous I/O request. -// -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - BOOLEAN IsEnd; - - EFI_BLOCK_IO2_TOKEN *Token; - EFI_EVENT Event; -} EMMC_REQUEST; - -#define EMMC_REQUEST_FROM_LINK(a) \ - CR(a, EMMC_REQUEST, Link, EMMC_REQUEST_SIGNATURE) - -typedef struct { - UINT32 Signature; - BOOLEAN Enable; - EMMC_PARTITION_TYPE PartitionType; - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_BLOCK_IO_PROTOCOL BlockIo; - EFI_BLOCK_IO2_PROTOCOL BlockIo2; - EFI_BLOCK_IO_MEDIA BlockMedia; - EFI_STORAGE_SECURITY_COMMAND_PROTOCOL StorageSecurity; - EFI_ERASE_BLOCK_PROTOCOL EraseBlock; - - LIST_ENTRY Queue; - - EMMC_DEVICE *Device; -} EMMC_PARTITION; - -// -// Up to 6 slots per EMMC PCI host controller -// -#define EMMC_MAX_DEVICES 6 -// -// Up to 8 partitions per EMMC device. -// -#define EMMC_MAX_PARTITIONS 8 -#define EMMC_MODEL_NAME_MAX_LEN 32 - -struct _EMMC_DEVICE { - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UINT8 Slot; - BOOLEAN SectorAddressing; - - EMMC_PARTITION Partition[EMMC_MAX_PARTITIONS]; - EMMC_CSD Csd; - EMMC_CID Cid; - EMMC_EXT_CSD ExtCsd; - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - // - // The model name consists of three fields in CID register - // 1) OEM/Application ID (2 bytes) - // 2) Product Name (5 bytes) - // 3) Product Serial Number (4 bytes) - // The delimiters of these fields are whitespace. - // - CHAR16 ModelName[EMMC_MODEL_NAME_MAX_LEN]; - EMMC_DRIVER_PRIVATE_DATA *Private; -} ; - -// -// EMMC DXE driver private data structure -// -struct _EMMC_DRIVER_PRIVATE_DATA { - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_HANDLE Controller; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_HANDLE DriverBindingHandle; - - EMMC_DEVICE Device[EMMC_MAX_DEVICES]; -} ; - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -EmmcDxeDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -EmmcDxeDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -EmmcDxeDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -EmmcDxeComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -EmmcDxeComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -/** - Send command SELECT to the device to select/deselect the device. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[in] Rca The relative device address to use. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcSelect ( - IN EMMC_DEVICE *Device, - IN UINT16 Rca - ); - -/** - Send command SEND_STATUS to the device to get device status. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] DevStatus The buffer to store the device status. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcSendStatus ( - IN EMMC_DEVICE *Device, - IN UINT16 Rca, - OUT UINT32 *DevStatus - ); - -/** - Send command SEND_CSD to the device to get the CSD register data. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] Csd The buffer to store the EMMC_CSD register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcGetCsd ( - IN EMMC_DEVICE *Device, - IN UINT16 Rca, - OUT EMMC_CSD *Csd - ); - -/** - Send command SEND_CID to the device to get the CID register data. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] Cid The buffer to store the EMMC_CID register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcGetCid ( - IN EMMC_DEVICE *Device, - IN UINT16 Rca, - OUT EMMC_CID *Cid - ); - -/** - Send command SEND_EXT_CSD to the device to get the EXT_CSD register data. - - @param[in] Device A pointer to the EMMC_DEVICE instance. - @param[out] ExtCsd The buffer to store the EXT_CSD register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -EmmcGetExtCsd ( - IN EMMC_DEVICE *Device, - OUT EMMC_EXT_CSD *ExtCsd - ); - -#endif - diff --git a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf b/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf deleted file mode 100644 index 7b0504937a..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf +++ /dev/null @@ -1,67 +0,0 @@ -## @file -# EmmcDxe driver is used to manage the EMMC device. -# -# It produces BlockIo, BlockIo2 and StorageSecurity protocols to allow upper layer -# access the EMMC device. -# -# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = EmmcDxe - MODULE_UNI_FILE = EmmcDxe.uni - FILE_GUID = 2145F72F-E6F1-4440-A828-59DC9AAB5F89 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = InitializeEmmcDxe - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# -# DRIVER_BINDING = gEmmcDxeDriverBinding -# COMPONENT_NAME = gEmmcDxeComponentName -# COMPONENT_NAME2 = gEmmcDxeComponentName2 -# - -[Sources.common] - ComponentName.c - EmmcDxe.c - EmmcDxe.h - EmmcBlockIo.c - EmmcBlockIo.h - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - DevicePathLib - UefiBootServicesTableLib - MemoryAllocationLib - BaseMemoryLib - UefiLib - BaseLib - UefiDriverEntryPoint - DebugLib - -[Protocols] - gEfiSdMmcPassThruProtocolGuid ## TO_START - gEfiBlockIoProtocolGuid ## BY_START - gEfiBlockIo2ProtocolGuid ## BY_START - gEfiStorageSecurityCommandProtocolGuid ## SOMETIMES_PRODUCES - gEfiEraseBlockProtocolGuid ## BY_START - ## TO_START - ## BY_START - gEfiDevicePathProtocolGuid - diff --git a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.uni b/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.uni deleted file mode 100644 index a0c9cf2935..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// EMMC device driver to manage the EMMC device and provide interface for upper layer -// access. -// -// Copyright (c) 2015, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "EMMC device driver to manage the EMMC device and provide interface for upper layer access" - -#string STR_MODULE_DESCRIPTION #language en-US "This driver follows the UEFI driver model and layers on the SdMmcPassThru protocol. It installs BlockIo/BlockIo2/StorageSecurity protocols for the EMMC device partitions." - diff --git a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxeExtra.uni b/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxeExtra.uni deleted file mode 100644 index 083b4f67ae..0000000000 --- a/MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxeExtra.uni +++ /dev/null @@ -1,19 +0,0 @@ -// /** @file -// EmmcDxe Localized Strings and Content -// -// Copyright (c) 2015, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"EMMC Device Driver" - - diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.c b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.c deleted file mode 100644 index 6dc343edbd..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.c +++ /dev/null @@ -1,617 +0,0 @@ -/** @file - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "SdBlockIoPei.h" - -// -// Template for SD HC Slot Data. -// -SD_PEIM_HC_SLOT gSdHcSlotTemplate = { - SD_PEIM_SLOT_SIG, // Signature - { // Media - MSG_SD_DP, - FALSE, - TRUE, - FALSE, - 0x200, - 0 - }, - 0, // SdHcBase - { // Capability - 0, - }, - { // Csd - 0, - }, - TRUE, // SectorAddressing - NULL // Private -}; - -// -// Template for SD HC Private Data. -// -SD_PEIM_HC_PRIVATE_DATA gSdHcPrivateTemplate = { - SD_PEIM_SIG, // Signature - NULL, // Pool - { // BlkIoPpi - SdBlockIoPeimGetDeviceNo, - SdBlockIoPeimGetMediaInfo, - SdBlockIoPeimReadBlocks - }, - { // BlkIo2Ppi - EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION, - SdBlockIoPeimGetDeviceNo2, - SdBlockIoPeimGetMediaInfo2, - SdBlockIoPeimReadBlocks2 - }, - { // BlkIoPpiList - EFI_PEI_PPI_DESCRIPTOR_PPI, - &gEfiPeiVirtualBlockIoPpiGuid, - NULL - }, - { // BlkIo2PpiList - EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, - &gEfiPeiVirtualBlockIo2PpiGuid, - NULL - }, - { // Slot - { - 0, - }, - { - 0, - }, - { - 0, - }, - { - 0, - }, - { - 0, - }, - { - 0, - } - }, - 0, // SlotNum - 0 // TotalBlkIoDevices -}; -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimGetDeviceNo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - OUT UINTN *NumberBlockDevices - ) -{ - SD_PEIM_HC_PRIVATE_DATA *Private; - - Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS (This); - *NumberBlockDevices = Private->TotalBlkIoDevices; - return EFI_SUCCESS; -} - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @par Note: - The MediaInfo structure describes an enumeration of possible block device - types. This enumeration exists because no device paths are actually passed - across interfaces that describe the type or class of hardware that is publishing - the block I/O interface. This enumeration will allow for policy decisions - in the Recovery PEIM, such as "Try to recover from legacy floppy first, - LS-120 second, CD-ROM third." If there are multiple partitions abstracted - by a given device type, they should be reported in ascending order; this - order also applies to nested partitions, such as legacy MBR, where the - outermost partitions would have precedence in the reporting order. The - same logic applies to systems such as IDE that have precedence relationships - like "Master/Slave" or "Primary/Secondary". The master device should be - reported first, the slave second. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimGetMediaInfo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo - ) -{ - SD_PEIM_HC_PRIVATE_DATA *Private; - - Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS (This); - - if ((DeviceIndex == 0) || (DeviceIndex > Private->TotalBlkIoDevices)) { - return EFI_INVALID_PARAMETER; - } - - MediaInfo->DeviceType = SD; - MediaInfo->MediaPresent = TRUE; - MediaInfo->LastBlock = (UINTN)Private->Slot[DeviceIndex - 1].Media.LastBlock; - MediaInfo->BlockSize = Private->Slot[DeviceIndex - 1].Media.BlockSize; - - return EFI_SUCCESS; -} - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimReadBlocks ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - UINT32 BlockSize; - UINTN NumberOfBlocks; - SD_PEIM_HC_PRIVATE_DATA *Private; - UINTN Remaining; - UINT32 MaxBlock; - - Status = EFI_SUCCESS; - Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS (This); - - // - // Check parameters - // - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - if ((DeviceIndex == 0) || (DeviceIndex > Private->TotalBlkIoDevices)) { - return EFI_INVALID_PARAMETER; - } - - BlockSize = Private->Slot[DeviceIndex - 1].Media.BlockSize; - if (BufferSize % BlockSize != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - if (StartLBA > Private->Slot[DeviceIndex - 1].Media.LastBlock) { - return EFI_INVALID_PARAMETER; - } - - NumberOfBlocks = BufferSize / BlockSize; - - // - // Start to execute data transfer. The max block number in single cmd is 65535 blocks. - // - Remaining = NumberOfBlocks; - MaxBlock = 0xFFFF; - - while (Remaining > 0) { - if (Remaining <= MaxBlock) { - NumberOfBlocks = Remaining; - } else { - NumberOfBlocks = MaxBlock; - } - - BufferSize = NumberOfBlocks * BlockSize; - if (NumberOfBlocks != 1) { - Status = SdPeimRwMultiBlocks (&Private->Slot[DeviceIndex - 1], StartLBA, BlockSize, Buffer, BufferSize, TRUE); - } else { - Status = SdPeimRwSingleBlock (&Private->Slot[DeviceIndex - 1], StartLBA, BlockSize, Buffer, BufferSize, TRUE); - } - if (EFI_ERROR (Status)) { - return Status; - } - - StartLBA += NumberOfBlocks; - Buffer = (UINT8*)Buffer + BufferSize; - Remaining -= NumberOfBlocks; - } - return Status; -} - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimGetDeviceNo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - OUT UINTN *NumberBlockDevices - ) -{ - SD_PEIM_HC_PRIVATE_DATA *Private; - - Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This); - *NumberBlockDevices = Private->TotalBlkIoDevices; - - return EFI_SUCCESS; -} - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @par Note: - The MediaInfo structure describes an enumeration of possible block device - types. This enumeration exists because no device paths are actually passed - across interfaces that describe the type or class of hardware that is publishing - the block I/O interface. This enumeration will allow for policy decisions - in the Recovery PEIM, such as "Try to recover from legacy floppy first, - LS-120 second, CD-ROM third." If there are multiple partitions abstracted - by a given device type, they should be reported in ascending order; this - order also applies to nested partitions, such as legacy MBR, where the - outermost partitions would have precedence in the reporting order. The - same logic applies to systems such as IDE that have precedence relationships - like "Master/Slave" or "Primary/Secondary". The master device should be - reported first, the slave second. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimGetMediaInfo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo - ) -{ - EFI_STATUS Status; - SD_PEIM_HC_PRIVATE_DATA *Private; - EFI_PEI_BLOCK_IO_MEDIA Media; - - Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This); - - Status = SdBlockIoPeimGetMediaInfo ( - PeiServices, - &Private->BlkIoPpi, - DeviceIndex, - &Media - ); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (MediaInfo, &(Private->Slot[DeviceIndex - 1].Media), sizeof (EFI_PEI_BLOCK_IO2_MEDIA)); - return EFI_SUCCESS; -} - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimReadBlocks2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - SD_PEIM_HC_PRIVATE_DATA *Private; - - Status = EFI_SUCCESS; - Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This); - - Status = SdBlockIoPeimReadBlocks ( - PeiServices, - &Private->BlkIoPpi, - DeviceIndex, - StartLBA, - BufferSize, - Buffer - ); - return Status; -} - -/** - The user code starts with this function. - - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCCESS The driver is successfully initialized. - @retval Others Can't initialize the driver. - -**/ -EFI_STATUS -EFIAPI -InitializeSdBlockIoPeim ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - EFI_STATUS Status; - SD_PEIM_HC_PRIVATE_DATA *Private; - EDKII_SD_MMC_HOST_CONTROLLER_PPI *SdMmcHcPpi; - UINT32 Index; - UINTN *MmioBase; - UINT8 BarNum; - UINT8 SlotNum; - UINT8 Controller; - UINT64 Capacity; - SD_HC_SLOT_CAP Capability; - SD_PEIM_HC_SLOT *Slot; - SD_CSD *Csd; - SD_CSD2 *Csd2; - UINT32 CSize; - UINT32 CSizeMul; - UINT32 ReadBlLen; - - // - // Shadow this PEIM to run from memory - // - if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { - return EFI_SUCCESS; - } - - // - // locate Sd host controller PPI - // - Status = PeiServicesLocatePpi ( - &gEdkiiPeiSdMmcHostControllerPpiGuid, - 0, - NULL, - (VOID **) &SdMmcHcPpi - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - Controller = 0; - MmioBase = NULL; - while (TRUE) { - Status = SdMmcHcPpi->GetSdMmcHcMmioBar (SdMmcHcPpi, Controller, &MmioBase, &BarNum); - // - // When status is error, meant no controller is found - // - if (EFI_ERROR (Status)) { - break; - } - - if (BarNum == 0) { - Controller++; - continue; - } - - Private = AllocateCopyPool (sizeof (SD_PEIM_HC_PRIVATE_DATA), &gSdHcPrivateTemplate); - if (Private == NULL) { - Status = EFI_OUT_OF_RESOURCES; - break; - } - Private->BlkIoPpiList.Ppi = (VOID*)&Private->BlkIoPpi; - Private->BlkIo2PpiList.Ppi = (VOID*)&Private->BlkIo2Ppi; - // - // Initialize the memory pool which will be used in all transactions. - // - Status = SdPeimInitMemPool (Private); - if (EFI_ERROR (Status)) { - Status = EFI_OUT_OF_RESOURCES; - break; - } - - for (Index = 0; Index < BarNum; Index++) { - Status = SdPeimHcGetCapability (MmioBase[Index], &Capability); - if (EFI_ERROR (Status)) { - continue; - } - if (Capability.SlotType != 0x1) { - DEBUG ((EFI_D_INFO, "The slot at 0x%x is not embedded slot type\n", MmioBase[Index])); - Status = EFI_UNSUPPORTED; - continue; - } - - Status = SdPeimHcReset (MmioBase[Index]); - if (EFI_ERROR (Status)) { - continue; - } - Status = SdPeimHcCardDetect (MmioBase[Index]); - if (EFI_ERROR (Status)) { - continue; - } - Status = SdPeimHcInitHost (MmioBase[Index]); - if (EFI_ERROR (Status)) { - continue; - } - - SlotNum = Private->SlotNum; - Slot = &Private->Slot[SlotNum]; - CopyMem (Slot, &gSdHcSlotTemplate, sizeof (SD_PEIM_HC_SLOT)); - Slot->Private = Private; - Slot->SdHcBase = MmioBase[Index]; - CopyMem (&Slot->Capability, &Capability, sizeof (Capability)); - - Status = SdPeimIdentification (Slot); - if (EFI_ERROR (Status)) { - continue; - } - - Csd = &Slot->Csd; - if (Csd->CsdStructure == 0) { - Slot->SectorAddressing = FALSE; - CSize = (Csd->CSizeHigh << 2 | Csd->CSizeLow) + 1; - CSizeMul = (1 << (Csd->CSizeMul + 2)); - ReadBlLen = (1 << (Csd->ReadBlLen)); - Capacity = MultU64x32 (MultU64x32 ((UINT64)CSize, CSizeMul), ReadBlLen); - } else { - Slot->SectorAddressing = TRUE; - Csd2 = (SD_CSD2*)(VOID*)Csd; - CSize = (Csd2->CSizeHigh << 16 | Csd2->CSizeLow) + 1; - Capacity = MultU64x32 ((UINT64)CSize, SIZE_512KB); - } - - Slot->Media.LastBlock = DivU64x32 (Capacity, Slot->Media.BlockSize) - 1; - - Private->TotalBlkIoDevices++; - Private->SlotNum++; - } - - Controller++; - if (!EFI_ERROR (Status)) { - PeiServicesInstallPpi (&Private->BlkIoPpiList); - } - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.h b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.h deleted file mode 100644 index b2491bb3cb..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.h +++ /dev/null @@ -1,377 +0,0 @@ -/** @file - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SD_BLOCK_IO_PEI_H_ -#define _SD_BLOCK_IO_PEI_H_ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef struct _SD_PEIM_HC_PRIVATE_DATA SD_PEIM_HC_PRIVATE_DATA; -typedef struct _SD_PEIM_HC_SLOT SD_PEIM_HC_SLOT; -typedef struct _SD_TRB SD_TRB; - -#include "SdHci.h" -#include "SdHcMem.h" - -#define SD_PEIM_SIG SIGNATURE_32 ('S', 'D', 'C', 'P') -#define SD_PEIM_SLOT_SIG SIGNATURE_32 ('S', 'D', 'C', 'S') - -#define SD_PEIM_MAX_SLOTS 6 - -struct _SD_PEIM_HC_SLOT { - UINT32 Signature; - EFI_PEI_BLOCK_IO2_MEDIA Media; - - UINTN SdHcBase; - SD_HC_SLOT_CAP Capability; - SD_CSD Csd; - BOOLEAN SectorAddressing; - SD_PEIM_HC_PRIVATE_DATA *Private; -}; - -struct _SD_PEIM_HC_PRIVATE_DATA { - UINT32 Signature; - SD_PEIM_MEM_POOL *Pool; - EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi; - EFI_PEI_RECOVERY_BLOCK_IO2_PPI BlkIo2Ppi; - EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList; - EFI_PEI_PPI_DESCRIPTOR BlkIo2PpiList; - SD_PEIM_HC_SLOT Slot[SD_PEIM_MAX_SLOTS]; - UINT8 SlotNum; - UINT8 TotalBlkIoDevices; -}; - -#define SD_TIMEOUT MultU64x32((UINT64)(3), 1000000) -#define GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS(a) CR (a, SD_PEIM_HC_PRIVATE_DATA, BlkIoPpi, SD_PEIM_SIG) -#define GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS2(a) CR (a, SD_PEIM_HC_PRIVATE_DATA, BlkIo2Ppi, SD_PEIM_SIG) - -struct _SD_TRB { - SD_PEIM_HC_SLOT *Slot; - UINT16 BlockSize; - - SD_COMMAND_PACKET *Packet; - VOID *Data; - UINT32 DataLen; - BOOLEAN Read; - SD_HC_TRANSFER_MODE Mode; - - UINT64 Timeout; - - SD_HC_ADMA_DESC_LINE *AdmaDesc; - UINTN AdmaDescSize; -}; - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimGetDeviceNo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - OUT UINTN *NumberBlockDevices - ); - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @par Note: - The MediaInfo structure describes an enumeration of possible block device - types. This enumeration exists because no device paths are actually passed - across interfaces that describe the type or class of hardware that is publishing - the block I/O interface. This enumeration will allow for policy decisions - in the Recovery PEIM, such as "Try to recover from legacy floppy first, - LS-120 second, CD-ROM third." If there are multiple partitions abstracted - by a given device type, they should be reported in ascending order; this - order also applies to nested partitions, such as legacy MBR, where the - outermost partitions would have precedence in the reporting order. The - same logic applies to systems such as IDE that have precedence relationships - like "Master/Slave" or "Primary/Secondary". The master device should be - reported first, the slave second. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimGetMediaInfo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo - ); - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimReadBlocks ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimGetDeviceNo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - OUT UINTN *NumberBlockDevices - ); - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @par Note: - The MediaInfo structure describes an enumeration of possible block device - types. This enumeration exists because no device paths are actually passed - across interfaces that describe the type or class of hardware that is publishing - the block I/O interface. This enumeration will allow for policy decisions - in the Recovery PEIM, such as "Try to recover from legacy floppy first, - LS-120 second, CD-ROM third." If there are multiple partitions abstracted - by a given device type, they should be reported in ascending order; this - order also applies to nested partitions, such as legacy MBR, where the - outermost partitions would have precedence in the reporting order. The - same logic applies to systems such as IDE that have precedence relationships - like "Master/Slave" or "Primary/Secondary". The master device should be - reported first, the slave second. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimGetMediaInfo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo - ); - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -SdBlockIoPeimReadBlocks2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Initialize the memory management pool for the host controller. - - @param Private The Sd Peim driver private data. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval Others Fail to init the memory pool. - -**/ -EFI_STATUS -SdPeimInitMemPool ( - IN SD_PEIM_HC_PRIVATE_DATA *Private - ); - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -SdPeimAllocateMem ( - IN SD_PEIM_MEM_POOL *Pool, - IN UINTN Size - ); - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -SdPeimFreeMem ( - IN SD_PEIM_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -#endif diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.inf b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.inf deleted file mode 100644 index ca4c39b65f..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.inf +++ /dev/null @@ -1,62 +0,0 @@ -## @file -# Description file for the SD memory card Peim driver. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = SdBlockIoPei - MODULE_UNI_FILE = SdBlockIoPei.uni - FILE_GUID = 17851FBF-45C4-4ff7-A2A0-C3B12D63C27E - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - - ENTRY_POINT = InitializeSdBlockIoPeim - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - SdBlockIoPei.c - SdBlockIoPei.h - SdHci.c - SdHci.h - SdHcMem.c - SdHcMem.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - IoLib - TimerLib - BaseMemoryLib - PeimEntryPoint - PeiServicesLib - DebugLib - -[Ppis] - gEfiPeiVirtualBlockIoPpiGuid ## PRODUCES - gEfiPeiVirtualBlockIo2PpiGuid ## PRODUCES - gEdkiiPeiSdMmcHostControllerPpiGuid ## CONSUMES - -[Depex] - gEfiPeiMemoryDiscoveredPpiGuid AND gEdkiiPeiSdMmcHostControllerPpiGuid - -[UserExtensions.TianoCore."ExtraFiles"] - SdBlockIoPeiExtra.uni - diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.uni b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.uni deleted file mode 100644 index 30c9f0e92c..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.uni +++ /dev/null @@ -1,21 +0,0 @@ -// /** @file -// The SdBlockIoPei driver is used to support recovery from SD memory card device. -// -// Copyright (c) 2015, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions -// of the BSD License which accompanies this distribution. The -// full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Support recovery from SD memory card devices" - -#string STR_MODULE_DESCRIPTION #language en-US "The SdBlockIoPei driver is used to support recovery from SD memory card device." - diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPeiExtra.uni b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPeiExtra.uni deleted file mode 100644 index 141e467233..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPeiExtra.uni +++ /dev/null @@ -1,21 +0,0 @@ -// /** @file -// SdBlockIoPei Localized Strings and Content -// -// Copyright (c) 2015, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions -// of the BSD License which accompanies this distribution. The -// full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"SD BlockIo Peim for Recovery" - - diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.c b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.c deleted file mode 100644 index f390a636dc..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.c +++ /dev/null @@ -1,455 +0,0 @@ -/** @file - -Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "SdBlockIoPei.h" - -/** - Allocate a block of memory to be used by the buffer pool. - - @param Pages How many pages to allocate. - - @return The allocated memory block or NULL if failed. - -**/ -SD_PEIM_MEM_BLOCK * -SdPeimAllocMemBlock ( - IN UINTN Pages - ) -{ - SD_PEIM_MEM_BLOCK *Block; - EFI_STATUS Status; - VOID *TempPtr; - EFI_PHYSICAL_ADDRESS Address; - - TempPtr = NULL; - Block = NULL; - - Status = PeiServicesAllocatePool (sizeof(SD_PEIM_MEM_BLOCK), &TempPtr); - if (EFI_ERROR (Status)) { - return NULL; - } - - ZeroMem ((VOID*)(UINTN)TempPtr, sizeof(SD_PEIM_MEM_BLOCK)); - - // - // each bit in the bit array represents SD_PEIM_MEM_UNIT - // bytes of memory in the memory block. - // - ASSERT (SD_PEIM_MEM_UNIT * 8 <= EFI_PAGE_SIZE); - - Block = (SD_PEIM_MEM_BLOCK*)(UINTN)TempPtr; - Block->BufLen = EFI_PAGES_TO_SIZE (Pages); - Block->BitsLen = Block->BufLen / (SD_PEIM_MEM_UNIT * 8); - - Status = PeiServicesAllocatePool (Block->BitsLen, &TempPtr); - if (EFI_ERROR (Status)) { - return NULL; - } - - ZeroMem ((VOID*)(UINTN)TempPtr, Block->BitsLen); - - Block->Bits = (UINT8*)(UINTN)TempPtr; - - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - Pages, - &Address - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - ZeroMem ((VOID*)(UINTN)Address, EFI_PAGES_TO_SIZE (Pages)); - - Block->Buf = (UINT8*)((UINTN)Address); - Block->Next = NULL; - - return Block; -} - -/** - Free the memory block from the memory pool. - - @param Pool The memory pool to free the block from. - @param Block The memory block to free. - -**/ -VOID -SdPeimFreeMemBlock ( - IN SD_PEIM_MEM_POOL *Pool, - IN SD_PEIM_MEM_BLOCK *Block - ) -{ - ASSERT ((Pool != NULL) && (Block != NULL)); -} - -/** - Alloc some memory from the block. - - @param Block The memory block to allocate memory from. - @param Units Number of memory units to allocate. - - @return The pointer to the allocated memory. If couldn't allocate the needed memory, - the return value is NULL. - -**/ -VOID * -SdPeimAllocMemFromBlock ( - IN SD_PEIM_MEM_BLOCK *Block, - IN UINTN Units - ) -{ - UINTN Byte; - UINT8 Bit; - UINTN StartByte; - UINT8 StartBit; - UINTN Available; - UINTN Count; - - ASSERT ((Block != 0) && (Units != 0)); - - StartByte = 0; - StartBit = 0; - Available = 0; - - for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) { - // - // If current bit is zero, the corresponding memory unit is - // available, otherwise we need to restart our searching. - // Available counts the consective number of zero bit. - // - if (!SD_PEIM_MEM_BIT_IS_SET (Block->Bits[Byte], Bit)) { - Available++; - - if (Available >= Units) { - break; - } - - SD_PEIM_NEXT_BIT (Byte, Bit); - - } else { - SD_PEIM_NEXT_BIT (Byte, Bit); - - Available = 0; - StartByte = Byte; - StartBit = Bit; - } - } - - if (Available < Units) { - return NULL; - } - - // - // Mark the memory as allocated - // - Byte = StartByte; - Bit = StartBit; - - for (Count = 0; Count < Units; Count++) { - ASSERT (!SD_PEIM_MEM_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) SD_PEIM_MEM_BIT (Bit)); - SD_PEIM_NEXT_BIT (Byte, Bit); - } - - return Block->Buf + (StartByte * 8 + StartBit) * SD_PEIM_MEM_UNIT; -} - -/** - Insert the memory block to the pool's list of the blocks. - - @param Head The head of the memory pool's block list. - @param Block The memory block to insert. - -**/ -VOID -SdPeimInsertMemBlockToPool ( - IN SD_PEIM_MEM_BLOCK *Head, - IN SD_PEIM_MEM_BLOCK *Block - ) -{ - ASSERT ((Head != NULL) && (Block != NULL)); - Block->Next = Head->Next; - Head->Next = Block; -} - -/** - Is the memory block empty? - - @param Block The memory block to check. - - @retval TRUE The memory block is empty. - @retval FALSE The memory block isn't empty. - -**/ -BOOLEAN -SdPeimIsMemBlockEmpty ( - IN SD_PEIM_MEM_BLOCK *Block - ) -{ - UINTN Index; - - - for (Index = 0; Index < Block->BitsLen; Index++) { - if (Block->Bits[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - -/** - Unlink the memory block from the pool's list. - - @param Head The block list head of the memory's pool. - @param BlockToUnlink The memory block to unlink. - -**/ -VOID -SdPeimUnlinkMemBlock ( - IN SD_PEIM_MEM_BLOCK *Head, - IN SD_PEIM_MEM_BLOCK *BlockToUnlink - ) -{ - SD_PEIM_MEM_BLOCK *Block; - - ASSERT ((Head != NULL) && (BlockToUnlink != NULL)); - - for (Block = Head; Block != NULL; Block = Block->Next) { - if (Block->Next == BlockToUnlink) { - Block->Next = BlockToUnlink->Next; - BlockToUnlink->Next = NULL; - break; - } - } -} - -/** - Initialize the memory management pool for the host controller. - - @param Private The Sd Peim driver private data. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval Others Fail to init the memory pool. - -**/ -EFI_STATUS -SdPeimInitMemPool ( - IN SD_PEIM_HC_PRIVATE_DATA *Private - ) -{ - SD_PEIM_MEM_POOL *Pool; - EFI_STATUS Status; - VOID *TempPtr; - - TempPtr = NULL; - Pool = NULL; - - Status = PeiServicesAllocatePool (sizeof (SD_PEIM_MEM_POOL), &TempPtr); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem ((VOID*)(UINTN)TempPtr, sizeof (SD_PEIM_MEM_POOL)); - - Pool = (SD_PEIM_MEM_POOL *)((UINTN)TempPtr); - - Pool->Head = SdPeimAllocMemBlock (SD_PEIM_MEM_DEFAULT_PAGES); - - if (Pool->Head == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Private->Pool = Pool; - return EFI_SUCCESS; -} - -/** - Release the memory management pool. - - @param Pool The memory pool to free. - - @retval EFI_DEVICE_ERROR Fail to free the memory pool. - @retval EFI_SUCCESS The memory pool is freed. - -**/ -EFI_STATUS -SdPeimFreeMemPool ( - IN SD_PEIM_MEM_POOL *Pool - ) -{ - SD_PEIM_MEM_BLOCK *Block; - - ASSERT (Pool->Head != NULL); - - // - // Unlink all the memory blocks from the pool, then free them. - // SdPeimUnlinkMemBlock can't be used to unlink and free the - // first block. - // - for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) { - SdPeimFreeMemBlock (Pool, Block); - } - - SdPeimFreeMemBlock (Pool, Pool->Head); - - return EFI_SUCCESS; -} - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -SdPeimAllocateMem ( - IN SD_PEIM_MEM_POOL *Pool, - IN UINTN Size - ) -{ - SD_PEIM_MEM_BLOCK *Head; - SD_PEIM_MEM_BLOCK *Block; - SD_PEIM_MEM_BLOCK *NewBlock; - VOID *Mem; - UINTN AllocSize; - UINTN Pages; - - Mem = NULL; - AllocSize = SD_PEIM_MEM_ROUND (Size); - Head = Pool->Head; - ASSERT (Head != NULL); - - // - // First check whether current memory blocks can satisfy the allocation. - // - for (Block = Head; Block != NULL; Block = Block->Next) { - Mem = SdPeimAllocMemFromBlock (Block, AllocSize / SD_PEIM_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - break; - } - } - - if (Mem != NULL) { - return Mem; - } - - // - // Create a new memory block if there is not enough memory - // in the pool. If the allocation size is larger than the - // default page number, just allocate a large enough memory - // block. Otherwise allocate default pages. - // - if (AllocSize > EFI_PAGES_TO_SIZE (SD_PEIM_MEM_DEFAULT_PAGES)) { - Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1; - } else { - Pages = SD_PEIM_MEM_DEFAULT_PAGES; - } - - NewBlock = SdPeimAllocMemBlock (Pages); - if (NewBlock == NULL) { - return NULL; - } - - // - // Add the new memory block to the pool, then allocate memory from it - // - SdPeimInsertMemBlockToPool (Head, NewBlock); - Mem = SdPeimAllocMemFromBlock (NewBlock, AllocSize / SD_PEIM_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - } - - return Mem; -} - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -SdPeimFreeMem ( - IN SD_PEIM_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - SD_PEIM_MEM_BLOCK *Head; - SD_PEIM_MEM_BLOCK *Block; - UINT8 *ToFree; - UINTN AllocSize; - UINTN Byte; - UINTN Bit; - UINTN Count; - - Head = Pool->Head; - AllocSize = SD_PEIM_MEM_ROUND (Size); - ToFree = (UINT8 *) Mem; - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the memory to free. - // - if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) { - // - // compute the start byte and bit in the bit array - // - Byte = ((ToFree - Block->Buf) / SD_PEIM_MEM_UNIT) / 8; - Bit = ((ToFree - Block->Buf) / SD_PEIM_MEM_UNIT) % 8; - - // - // reset associated bits in bit array - // - for (Count = 0; Count < (AllocSize / SD_PEIM_MEM_UNIT); Count++) { - ASSERT (SD_PEIM_MEM_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ SD_PEIM_MEM_BIT (Bit)); - SD_PEIM_NEXT_BIT (Byte, Bit); - } - - break; - } - } - - // - // If Block == NULL, it means that the current memory isn't - // in the host controller's pool. This is critical because - // the caller has passed in a wrong memory point - // - ASSERT (Block != NULL); - - // - // Release the current memory block if it is empty and not the head - // - if ((Block != Head) && SdPeimIsMemBlockEmpty (Block)) { - SdPeimFreeMemBlock (Pool, Block); - } - - return ; -} diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.h b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.h deleted file mode 100644 index 096b625f98..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHcMem.h +++ /dev/null @@ -1,61 +0,0 @@ -/** @file - -Copyright (c) 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SD_PEIM_MEM_H_ -#define _SD_PEIM_MEM_H_ - -#define SD_PEIM_MEM_BIT(a) ((UINTN)(1 << (a))) - -#define SD_PEIM_MEM_BIT_IS_SET(Data, Bit) \ - ((BOOLEAN)(((Data) & SD_PEIM_MEM_BIT(Bit)) == SD_PEIM_MEM_BIT(Bit))) - -typedef struct _SD_PEIM_MEM_BLOCK SD_PEIM_MEM_BLOCK; - -struct _SD_PEIM_MEM_BLOCK { - UINT8 *Bits; // Bit array to record which unit is allocated - UINTN BitsLen; - UINT8 *Buf; - UINTN BufLen; // Memory size in bytes - SD_PEIM_MEM_BLOCK *Next; -}; - -typedef struct _SD_PEIM_MEM_POOL { - SD_PEIM_MEM_BLOCK *Head; -} SD_PEIM_MEM_POOL; - -// -// Memory allocation unit, note that the value must meet SD spec alignment requirement. -// -#define SD_PEIM_MEM_UNIT 128 - -#define SD_PEIM_MEM_UNIT_MASK (SD_PEIM_MEM_UNIT - 1) -#define SD_PEIM_MEM_DEFAULT_PAGES 16 - -#define SD_PEIM_MEM_ROUND(Len) (((Len) + SD_PEIM_MEM_UNIT_MASK) & (~SD_PEIM_MEM_UNIT_MASK)) - -// -// Advance the byte and bit to the next bit, adjust byte accordingly. -// -#define SD_PEIM_NEXT_BIT(Byte, Bit) \ - do { \ - (Bit)++; \ - if ((Bit) > 7) { \ - (Byte)++; \ - (Bit) = 0; \ - } \ - } while (0) - -#endif - diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c deleted file mode 100644 index eebadd79bc..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c +++ /dev/null @@ -1,2941 +0,0 @@ -/** @file - - Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "SdBlockIoPei.h" - -/** - Read/Write specified SD host controller mmio register. - - @param[in] Address The address of the mmio register to be read/written. - @param[in] Read A boolean to indicate it's read or write operation. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2 , 4 or 8 bytes. - @param[in, out] Data For read operations, the destination buffer to store - the results. For write operations, the source buffer - to write data from. The caller is responsible for - having ownership of the data buffer and ensuring its - size not less than Count bytes. - - @retval EFI_INVALID_PARAMETER The Address or the Data or the Count is not valid. - @retval EFI_SUCCESS The read/write operation succeeds. - @retval Others The read/write operation fails. - -**/ -EFI_STATUS -EFIAPI -SdPeimHcRwMmio ( - IN UINTN Address, - IN BOOLEAN Read, - IN UINT8 Count, - IN OUT VOID *Data - ) -{ - if ((Address == 0) || (Data == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Count != 1) && (Count != 2) && (Count != 4) && (Count != 8)) { - return EFI_INVALID_PARAMETER; - } - - switch (Count) { - case 1: - if (Read) { - *(UINT8*)Data = MmioRead8 (Address); - } else { - MmioWrite8 (Address, *(UINT8*)Data); - } - break; - case 2: - if (Read) { - *(UINT16*)Data = MmioRead16 (Address); - } else { - MmioWrite16 (Address, *(UINT16*)Data); - } - break; - case 4: - if (Read) { - *(UINT32*)Data = MmioRead32 (Address); - } else { - MmioWrite32 (Address, *(UINT32*)Data); - } - break; - case 8: - if (Read) { - *(UINT64*)Data = MmioRead64 (Address); - } else { - MmioWrite64 (Address, *(UINT64*)Data); - } - break; - default: - ASSERT (FALSE); - return EFI_INVALID_PARAMETER; - } - - return EFI_SUCCESS; -} - -/** - Do OR operation with the value of the specified SD host controller mmio register. - - @param[in] Address The address of the mmio register to be read/written. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2 , 4 or 8 bytes. - @param[in] OrData The pointer to the data used to do OR operation. - The caller is responsible for having ownership of - the data buffer and ensuring its size not less than - Count bytes. - - @retval EFI_INVALID_PARAMETER The Address or the OrData or the Count is not valid. - @retval EFI_SUCCESS The OR operation succeeds. - @retval Others The OR operation fails. - -**/ -EFI_STATUS -EFIAPI -SdPeimHcOrMmio ( - IN UINTN Address, - IN UINT8 Count, - IN VOID *OrData - ) -{ - EFI_STATUS Status; - UINT64 Data; - UINT64 Or; - - Status = SdPeimHcRwMmio (Address, TRUE, Count, &Data); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Count == 1) { - Or = *(UINT8*) OrData; - } else if (Count == 2) { - Or = *(UINT16*) OrData; - } else if (Count == 4) { - Or = *(UINT32*) OrData; - } else if (Count == 8) { - Or = *(UINT64*) OrData; - } else { - return EFI_INVALID_PARAMETER; - } - - Data |= Or; - Status = SdPeimHcRwMmio (Address, FALSE, Count, &Data); - - return Status; -} - -/** - Do AND operation with the value of the specified SD host controller mmio register. - - @param[in] Address The address of the mmio register to be read/written. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2 , 4 or 8 bytes. - @param[in] AndData The pointer to the data used to do AND operation. - The caller is responsible for having ownership of - the data buffer and ensuring its size not less than - Count bytes. - - @retval EFI_INVALID_PARAMETER The Address or the AndData or the Count is not valid. - @retval EFI_SUCCESS The AND operation succeeds. - @retval Others The AND operation fails. - -**/ -EFI_STATUS -EFIAPI -SdPeimHcAndMmio ( - IN UINTN Address, - IN UINT8 Count, - IN VOID *AndData - ) -{ - EFI_STATUS Status; - UINT64 Data; - UINT64 And; - - Status = SdPeimHcRwMmio (Address, TRUE, Count, &Data); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Count == 1) { - And = *(UINT8*) AndData; - } else if (Count == 2) { - And = *(UINT16*) AndData; - } else if (Count == 4) { - And = *(UINT32*) AndData; - } else if (Count == 8) { - And = *(UINT64*) AndData; - } else { - return EFI_INVALID_PARAMETER; - } - - Data &= And; - Status = SdPeimHcRwMmio (Address, FALSE, Count, &Data); - - return Status; -} - -/** - Wait for the value of the specified MMIO register set to the test value. - - @param[in] Address The address of the mmio register to be checked. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2, 4 or 8 bytes. - @param[in] MaskValue The mask value of memory. - @param[in] TestValue The test value of memory. - - @retval EFI_NOT_READY The MMIO register hasn't set to the expected value. - @retval EFI_SUCCESS The MMIO register has expected value. - @retval Others The MMIO operation fails. - -**/ -EFI_STATUS -EFIAPI -SdPeimHcCheckMmioSet ( - IN UINTN Address, - IN UINT8 Count, - IN UINT64 MaskValue, - IN UINT64 TestValue - ) -{ - EFI_STATUS Status; - UINT64 Value; - - // - // Access PCI MMIO space to see if the value is the tested one. - // - Value = 0; - Status = SdPeimHcRwMmio (Address, TRUE, Count, &Value); - if (EFI_ERROR (Status)) { - return Status; - } - - Value &= MaskValue; - - if (Value == TestValue) { - return EFI_SUCCESS; - } - - return EFI_NOT_READY; -} - -/** - Wait for the value of the specified MMIO register set to the test value. - - @param[in] Address The address of the mmio register to wait. - @param[in] Count The width of the mmio register in bytes. - Must be 1, 2, 4 or 8 bytes. - @param[in] MaskValue The mask value of memory. - @param[in] TestValue The test value of memory. - @param[in] Timeout The time out value for wait memory set, uses 1 - microsecond as a unit. - - @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout - range. - @retval EFI_SUCCESS The MMIO register has expected value. - @retval Others The MMIO operation fails. - -**/ -EFI_STATUS -EFIAPI -SdPeimHcWaitMmioSet ( - IN UINTN Address, - IN UINT8 Count, - IN UINT64 MaskValue, - IN UINT64 TestValue, - IN UINT64 Timeout - ) -{ - EFI_STATUS Status; - BOOLEAN InfiniteWait; - - if (Timeout == 0) { - InfiniteWait = TRUE; - } else { - InfiniteWait = FALSE; - } - - while (InfiniteWait || (Timeout > 0)) { - Status = SdPeimHcCheckMmioSet ( - Address, - Count, - MaskValue, - TestValue - ); - if (Status != EFI_NOT_READY) { - return Status; - } - - // - // Stall for 1 microsecond. - // - MicroSecondDelay (1); - - Timeout--; - } - - return EFI_TIMEOUT; -} - -/** - Software reset the specified SD host controller and enable all interrupts. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The software reset executes successfully. - @retval Others The software reset fails. - -**/ -EFI_STATUS -SdPeimHcReset ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT8 SwReset; - - SwReset = 0xFF; - Status = SdPeimHcRwMmio (Bar + SD_HC_SW_RST, FALSE, sizeof (SwReset), &SwReset); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimHcReset: write full 1 fails: %r\n", Status)); - return Status; - } - - Status = SdPeimHcWaitMmioSet ( - Bar + SD_HC_SW_RST, - sizeof (SwReset), - 0xFF, - 0x00, - SD_TIMEOUT - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, "SdPeimHcReset: reset done with %r\n", Status)); - return Status; - } - // - // Enable all interrupt after reset all. - // - Status = SdPeimHcEnableInterrupt (Bar); - - return Status; -} - -/** - Set all interrupt status bits in Normal and Error Interrupt Status Enable - register. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The operation executes successfully. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimHcEnableInterrupt ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT16 IntStatus; - - // - // Enable all bits in Error Interrupt Status Enable Register - // - IntStatus = 0xFFFF; - Status = SdPeimHcRwMmio (Bar + SD_HC_ERR_INT_STS_EN, FALSE, sizeof (IntStatus), &IntStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Enable all bits in Normal Interrupt Status Enable Register - // - IntStatus = 0xFFFF; - Status = SdPeimHcRwMmio (Bar + SD_HC_NOR_INT_STS_EN, FALSE, sizeof (IntStatus), &IntStatus); - - return Status; -} - -/** - Get the capability data from the specified slot. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[out] Capability The buffer to store the capability data. - - @retval EFI_SUCCESS The operation executes successfully. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimHcGetCapability ( - IN UINTN Bar, - OUT SD_HC_SLOT_CAP *Capability - ) -{ - EFI_STATUS Status; - UINT64 Cap; - - Status = SdPeimHcRwMmio (Bar + SD_HC_CAP, TRUE, sizeof (Cap), &Cap); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (Capability, &Cap, sizeof (Cap)); - - return EFI_SUCCESS; -} - -/** - Detect whether there is a SD card attached at the specified SD host controller - slot. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS There is a SD card attached. - @retval EFI_NO_MEDIA There is not a SD card attached. - @retval Others The detection fails. - -**/ -EFI_STATUS -SdPeimHcCardDetect ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT16 Data; - UINT32 PresentState; - - // - // Check Normal Interrupt Status Register - // - Status = SdPeimHcRwMmio (Bar + SD_HC_NOR_INT_STS, TRUE, sizeof (Data), &Data); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((Data & (BIT6 | BIT7)) != 0) { - // - // Clear BIT6 and BIT7 by writing 1 to these two bits if set. - // - Data &= BIT6 | BIT7; - Status = SdPeimHcRwMmio (Bar + SD_HC_NOR_INT_STS, FALSE, sizeof (Data), &Data); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Check Present State Register to see if there is a card presented. - // - Status = SdPeimHcRwMmio (Bar + SD_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((PresentState & BIT16) != 0) { - return EFI_SUCCESS; - } else { - return EFI_NO_MEDIA; - } -} - -/** - Stop SD card clock. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.2.2 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS Succeed to stop SD clock. - @retval Others Fail to stop SD clock. - -**/ -EFI_STATUS -SdPeimHcStopClock ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT32 PresentState; - UINT16 ClockCtrl; - - // - // Ensure no SD transactions are occurring on the SD Bus by - // waiting for Command Inhibit (DAT) and Command Inhibit (CMD) - // in the Present State register to be 0. - // - Status = SdPeimHcWaitMmioSet ( - Bar + SD_HC_PRESENT_STATE, - sizeof (PresentState), - BIT0 | BIT1, - 0, - SD_TIMEOUT - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Set SD Clock Enable in the Clock Control register to 0 - // - ClockCtrl = (UINT16)~BIT2; - Status = SdPeimHcAndMmio (Bar + SD_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl); - - return Status; -} - -/** - SD card clock supply. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.2.1 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] ClockFreq The max clock frequency to be set. The unit is KHz. - - @retval EFI_SUCCESS The clock is supplied successfully. - @retval Others The clock isn't supplied successfully. - -**/ -EFI_STATUS -SdPeimHcClockSupply ( - IN UINTN Bar, - IN UINT64 ClockFreq - ) -{ - EFI_STATUS Status; - SD_HC_SLOT_CAP Capability; - UINT32 BaseClkFreq; - UINT32 SettingFreq; - UINT32 Divisor; - UINT32 Remainder; - UINT16 ControllerVer; - UINT16 ClockCtrl; - - // - // Calculate a divisor for SD clock frequency - // - Status = SdPeimHcGetCapability (Bar, &Capability); - if (EFI_ERROR (Status)) { - return Status; - } - ASSERT (Capability.BaseClkFreq != 0); - - BaseClkFreq = Capability.BaseClkFreq; - - if (ClockFreq == 0) { - return EFI_INVALID_PARAMETER; - } - - if (ClockFreq > (BaseClkFreq * 1000)) { - ClockFreq = BaseClkFreq * 1000; - } - - // - // Calculate the divisor of base frequency. - // - Divisor = 0; - SettingFreq = BaseClkFreq * 1000; - while (ClockFreq < SettingFreq) { - Divisor++; - - SettingFreq = (BaseClkFreq * 1000) / (2 * Divisor); - Remainder = (BaseClkFreq * 1000) % (2 * Divisor); - if ((ClockFreq == SettingFreq) && (Remainder == 0)) { - break; - } - if ((ClockFreq == SettingFreq) && (Remainder != 0)) { - SettingFreq ++; - } - } - - DEBUG ((EFI_D_INFO, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq)); - - Status = SdPeimHcRwMmio (Bar + SD_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register. - // - if ((ControllerVer & 0xFF) == 2) { - ASSERT (Divisor <= 0x3FF); - ClockCtrl = ((Divisor & 0xFF) << 8) | ((Divisor & 0x300) >> 2); - } else if (((ControllerVer & 0xFF) == 0) || ((ControllerVer & 0xFF) == 1)) { - // - // Only the most significant bit can be used as divisor. - // - if (((Divisor - 1) & Divisor) != 0) { - Divisor = 1 << (HighBitSet32 (Divisor) + 1); - } - ASSERT (Divisor <= 0x80); - ClockCtrl = (Divisor & 0xFF) << 8; - } else { - DEBUG ((EFI_D_ERROR, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer)); - return EFI_UNSUPPORTED; - } - - // - // Stop bus clock at first - // - Status = SdPeimHcStopClock (Bar); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Supply clock frequency with specified divisor - // - ClockCtrl |= BIT0; - Status = SdPeimHcRwMmio (Bar + SD_HC_CLOCK_CTRL, FALSE, sizeof (ClockCtrl), &ClockCtrl); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n")); - return Status; - } - - // - // Wait Internal Clock Stable in the Clock Control register to be 1 - // - Status = SdPeimHcWaitMmioSet ( - Bar + SD_HC_CLOCK_CTRL, - sizeof (ClockCtrl), - BIT1, - BIT1, - SD_TIMEOUT - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Set SD Clock Enable in the Clock Control register to 1 - // - ClockCtrl = BIT2; - Status = SdPeimHcOrMmio (Bar + SD_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl); - - return Status; -} - -/** - SD bus power control. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] PowerCtrl The value setting to the power control register. - - @retval TRUE There is a SD card attached. - @retval FALSE There is no a SD card attached. - -**/ -EFI_STATUS -SdPeimHcPowerControl ( - IN UINTN Bar, - IN UINT8 PowerCtrl - ) -{ - EFI_STATUS Status; - - // - // Clr SD Bus Power - // - PowerCtrl &= (UINT8)~BIT0; - Status = SdPeimHcRwMmio (Bar + SD_HC_POWER_CTRL, FALSE, sizeof (PowerCtrl), &PowerCtrl); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register - // - PowerCtrl |= BIT0; - Status = SdPeimHcRwMmio (Bar + SD_HC_POWER_CTRL, FALSE, sizeof (PowerCtrl), &PowerCtrl); - - return Status; -} - -/** - Set the SD bus width. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] BusWidth The bus width used by the SD device, it must be 1, 4 or 8. - - @retval EFI_SUCCESS The bus width is set successfully. - @retval Others The bus width isn't set successfully. - -**/ -EFI_STATUS -SdPeimHcSetBusWidth ( - IN UINTN Bar, - IN UINT16 BusWidth - ) -{ - EFI_STATUS Status; - UINT8 HostCtrl1; - - if (BusWidth == 1) { - HostCtrl1 = (UINT8)~(BIT5 | BIT1); - Status = SdPeimHcAndMmio (Bar + SD_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - } else if (BusWidth == 4) { - Status = SdPeimHcRwMmio (Bar + SD_HC_HOST_CTRL1, TRUE, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - HostCtrl1 |= BIT1; - HostCtrl1 &= (UINT8)~BIT5; - Status = SdPeimHcRwMmio (Bar + SD_HC_HOST_CTRL1, FALSE, sizeof (HostCtrl1), &HostCtrl1); - } else if (BusWidth == 8) { - Status = SdPeimHcRwMmio (Bar + SD_HC_HOST_CTRL1, TRUE, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - HostCtrl1 &= (UINT8)~BIT1; - HostCtrl1 |= BIT5; - Status = SdPeimHcRwMmio (Bar + SD_HC_HOST_CTRL1, FALSE, sizeof (HostCtrl1), &HostCtrl1); - } else { - ASSERT (FALSE); - return EFI_INVALID_PARAMETER; - } - - return Status; -} - -/** - Supply SD card with lowest clock frequency at initialization. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The clock is supplied successfully. - @retval Others The clock isn't supplied successfully. - -**/ -EFI_STATUS -SdPeimHcInitClockFreq ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - SD_HC_SLOT_CAP Capability; - UINT32 InitFreq; - - // - // Calculate a divisor for SD clock frequency - // - Status = SdPeimHcGetCapability (Bar, &Capability); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Capability.BaseClkFreq == 0) { - // - // Don't support get Base Clock Frequency information via another method - // - return EFI_UNSUPPORTED; - } - // - // Supply 400KHz clock frequency at initialization phase. - // - InitFreq = 400; - Status = SdPeimHcClockSupply (Bar, InitFreq); - return Status; -} - -/** - Supply SD card with maximum voltage at initialization. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The voltage is supplied successfully. - @retval Others The voltage isn't supplied successfully. - -**/ -EFI_STATUS -SdPeimHcInitPowerVoltage ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - SD_HC_SLOT_CAP Capability; - UINT8 MaxVoltage; - UINT8 HostCtrl2; - - // - // Get the support voltage of the Host Controller - // - Status = SdPeimHcGetCapability (Bar, &Capability); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Calculate supported maximum voltage according to SD Bus Voltage Select - // - if (Capability.Voltage33 != 0) { - // - // Support 3.3V - // - MaxVoltage = 0x0E; - } else if (Capability.Voltage30 != 0) { - // - // Support 3.0V - // - MaxVoltage = 0x0C; - } else if (Capability.Voltage18 != 0) { - // - // Support 1.8V - // - MaxVoltage = 0x0A; - HostCtrl2 = BIT3; - Status = SdPeimHcOrMmio (Bar + SD_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - MicroSecondDelay (5000); - } else { - ASSERT (FALSE); - return EFI_DEVICE_ERROR; - } - - // - // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register - // - Status = SdPeimHcPowerControl (Bar, MaxVoltage); - - return Status; -} - -/** - Initialize the Timeout Control register with most conservative value at initialization. - - Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The timeout control register is configured successfully. - @retval Others The timeout control register isn't configured successfully. - -**/ -EFI_STATUS -SdPeimHcInitTimeoutCtrl ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - UINT8 Timeout; - - Timeout = 0x0E; - Status = SdPeimHcRwMmio (Bar + SD_HC_TIMEOUT_CTRL, FALSE, sizeof (Timeout), &Timeout); - - return Status; -} - -/** - Initial SD host controller with lowest clock frequency, max power and max timeout value - at initialization. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The host controller is initialized successfully. - @retval Others The host controller isn't initialized successfully. - -**/ -EFI_STATUS -SdPeimHcInitHost ( - IN UINTN Bar - ) -{ - EFI_STATUS Status; - - Status = SdPeimHcInitClockFreq (Bar); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdPeimHcInitPowerVoltage (Bar); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdPeimHcInitTimeoutCtrl (Bar); - return Status; -} - -/** - Turn on/off LED. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] On The boolean to turn on/off LED. - - @retval EFI_SUCCESS The LED is turned on/off successfully. - @retval Others The LED isn't turned on/off successfully. - -**/ -EFI_STATUS -SdPeimHcLedOnOff ( - IN UINTN Bar, - IN BOOLEAN On - ) -{ - EFI_STATUS Status; - UINT8 HostCtrl1; - - if (On) { - HostCtrl1 = BIT0; - Status = SdPeimHcOrMmio (Bar + SD_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - } else { - HostCtrl1 = (UINT8)~BIT0; - Status = SdPeimHcAndMmio (Bar + SD_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - } - - return Status; -} - -/** - Build ADMA descriptor table for transfer. - - Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details. - - @param[in] Trb The pointer to the SD_TRB instance. - - @retval EFI_SUCCESS The ADMA descriptor table is created successfully. - @retval Others The ADMA descriptor table isn't created successfully. - -**/ -EFI_STATUS -BuildAdmaDescTable ( - IN SD_TRB *Trb - ) -{ - EFI_PHYSICAL_ADDRESS Data; - UINT64 DataLen; - UINT64 Entries; - UINT32 Index; - UINT64 Remaining; - UINT32 Address; - - Data = (EFI_PHYSICAL_ADDRESS)(UINTN)Trb->Data; - DataLen = Trb->DataLen; - // - // Only support 32bit ADMA Descriptor Table - // - if ((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul)) { - return EFI_INVALID_PARAMETER; - } - // - // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0) - // for 32-bit address descriptor table. - // - if ((Data & (BIT0 | BIT1)) != 0) { - DEBUG ((EFI_D_INFO, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data)); - } - - Entries = DivU64x32 ((DataLen + ADMA_MAX_DATA_PER_LINE - 1), ADMA_MAX_DATA_PER_LINE); - - Trb->AdmaDescSize = (UINTN)MultU64x32 (Entries, sizeof (SD_HC_ADMA_DESC_LINE)); - Trb->AdmaDesc = SdPeimAllocateMem (Trb->Slot->Private->Pool, Trb->AdmaDescSize); - if (Trb->AdmaDesc == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Remaining = DataLen; - Address = (UINT32)Data; - for (Index = 0; Index < Entries; Index++) { - if (Remaining <= ADMA_MAX_DATA_PER_LINE) { - Trb->AdmaDesc[Index].Valid = 1; - Trb->AdmaDesc[Index].Act = 2; - Trb->AdmaDesc[Index].Length = (UINT16)Remaining; - Trb->AdmaDesc[Index].Address = Address; - break; - } else { - Trb->AdmaDesc[Index].Valid = 1; - Trb->AdmaDesc[Index].Act = 2; - Trb->AdmaDesc[Index].Length = 0; - Trb->AdmaDesc[Index].Address = Address; - } - - Remaining -= ADMA_MAX_DATA_PER_LINE; - Address += ADMA_MAX_DATA_PER_LINE; - } - - // - // Set the last descriptor line as end of descriptor table - // - Trb->AdmaDesc[Index].End = 1; - return EFI_SUCCESS; -} - -/** - Create a new TRB for the SD cmd request. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Packet A pointer to the SD command data structure. - - @return Created Trb or NULL. - -**/ -SD_TRB * -SdPeimCreateTrb ( - IN SD_PEIM_HC_SLOT *Slot, - IN SD_COMMAND_PACKET *Packet - ) -{ - SD_TRB *Trb; - EFI_STATUS Status; - SD_HC_SLOT_CAP Capability; - - // - // Calculate a divisor for SD clock frequency - // - Status = SdPeimHcGetCapability (Slot->SdHcBase, &Capability); - if (EFI_ERROR (Status)) { - return NULL; - } - - Trb = SdPeimAllocateMem (Slot->Private->Pool, sizeof (SD_TRB)); - if (Trb == NULL) { - return NULL; - } - - Trb->Slot = Slot; - Trb->BlockSize = 0x200; - Trb->Packet = Packet; - Trb->Timeout = Packet->Timeout; - - if ((Packet->InTransferLength != 0) && (Packet->InDataBuffer != NULL)) { - Trb->Data = Packet->InDataBuffer; - Trb->DataLen = Packet->InTransferLength; - Trb->Read = TRUE; - } else if ((Packet->OutTransferLength != 0) && (Packet->OutDataBuffer != NULL)) { - Trb->Data = Packet->OutDataBuffer; - Trb->DataLen = Packet->OutTransferLength; - Trb->Read = FALSE; - } else if ((Packet->InTransferLength == 0) && (Packet->OutTransferLength == 0)) { - Trb->Data = NULL; - Trb->DataLen = 0; - } else { - goto Error; - } - - if ((Trb->DataLen != 0) && (Trb->DataLen < Trb->BlockSize)) { - Trb->BlockSize = (UINT16)Trb->DataLen; - } - - if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) { - Trb->Mode = SdPioMode; - } else { - if (Trb->DataLen == 0) { - Trb->Mode = SdNoData; - } else if (Capability.Adma2 != 0) { - Trb->Mode = SdAdmaMode; - Status = BuildAdmaDescTable (Trb); - if (EFI_ERROR (Status)) { - goto Error; - } - } else if (Capability.Sdma != 0) { - Trb->Mode = SdSdmaMode; - } else { - Trb->Mode = SdPioMode; - } - } - return Trb; - -Error: - SdPeimFreeTrb (Trb); - return NULL; -} - -/** - Free the resource used by the TRB. - - @param[in] Trb The pointer to the SD_TRB instance. - -**/ -VOID -SdPeimFreeTrb ( - IN SD_TRB *Trb - ) -{ - if ((Trb != NULL) && (Trb->AdmaDesc != NULL)) { - SdPeimFreeMem (Trb->Slot->Private->Pool, Trb->AdmaDesc, Trb->AdmaDescSize); - } - - if (Trb != NULL) { - SdPeimFreeMem (Trb->Slot->Private->Pool, Trb, sizeof (SD_TRB)); - } - return; -} - -/** - Check if the env is ready for execute specified TRB. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the SD_TRB instance. - - @retval EFI_SUCCESS The env is ready for TRB execution. - @retval EFI_NOT_READY The env is not ready for TRB execution. - @retval Others Some erros happen. - -**/ -EFI_STATUS -SdPeimCheckTrbEnv ( - IN UINTN Bar, - IN SD_TRB *Trb - ) -{ - EFI_STATUS Status; - SD_COMMAND_PACKET *Packet; - UINT32 PresentState; - - Packet = Trb->Packet; - - if ((Packet->SdCmdBlk->CommandType == SdCommandTypeAdtc) || - (Packet->SdCmdBlk->ResponseType == SdResponseTypeR1b) || - (Packet->SdCmdBlk->ResponseType == SdResponseTypeR5b)) { - // - // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in - // the Present State register to be 0 - // - PresentState = BIT0 | BIT1; - } else { - // - // Wait Command Inhibit (CMD) in the Present State register - // to be 0 - // - PresentState = BIT0; - } - - Status = SdPeimHcCheckMmioSet ( - Bar + SD_HC_PRESENT_STATE, - sizeof (PresentState), - PresentState, - 0 - ); - - return Status; -} - -/** - Wait for the env to be ready for execute specified TRB. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the SD_TRB instance. - - @retval EFI_SUCCESS The env is ready for TRB execution. - @retval EFI_TIMEOUT The env is not ready for TRB execution in time. - @retval Others Some erros happen. - -**/ -EFI_STATUS -SdPeimWaitTrbEnv ( - IN UINTN Bar, - IN SD_TRB *Trb - ) -{ - EFI_STATUS Status; - SD_COMMAND_PACKET *Packet; - UINT64 Timeout; - BOOLEAN InfiniteWait; - - // - // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register - // - Packet = Trb->Packet; - Timeout = Packet->Timeout; - if (Timeout == 0) { - InfiniteWait = TRUE; - } else { - InfiniteWait = FALSE; - } - - while (InfiniteWait || (Timeout > 0)) { - // - // Check Trb execution result by reading Normal Interrupt Status register. - // - Status = SdPeimCheckTrbEnv (Bar, Trb); - if (Status != EFI_NOT_READY) { - return Status; - } - // - // Stall for 1 microsecond. - // - MicroSecondDelay (1); - - Timeout--; - } - - return EFI_TIMEOUT; -} - -/** - Execute the specified TRB. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the SD_TRB instance. - - @retval EFI_SUCCESS The TRB is sent to host controller successfully. - @retval Others Some erros happen when sending this request to the host controller. - -**/ -EFI_STATUS -SdPeimExecTrb ( - IN UINTN Bar, - IN SD_TRB *Trb - ) -{ - EFI_STATUS Status; - SD_COMMAND_PACKET *Packet; - UINT16 Cmd; - UINT16 IntStatus; - UINT32 Argument; - UINT16 BlkCount; - UINT16 BlkSize; - UINT16 TransMode; - UINT8 HostCtrl1; - UINT32 SdmaAddr; - UINT64 AdmaAddr; - - Packet = Trb->Packet; - // - // Clear all bits in Error Interrupt Status Register - // - IntStatus = 0xFFFF; - Status = SdPeimHcRwMmio (Bar + SD_HC_ERR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Clear all bits in Normal Interrupt Status Register - // - IntStatus = 0xFFFF; - Status = SdPeimHcRwMmio (Bar + SD_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Set Host Control 1 register DMA Select field - // - if (Trb->Mode == SdAdmaMode) { - HostCtrl1 = BIT4; - Status = SdPeimHcOrMmio (Bar + SD_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - } - - SdPeimHcLedOnOff (Bar, TRUE); - - if (Trb->Mode == SdSdmaMode) { - if ((UINT64)(UINTN)Trb->Data >= 0x100000000ul) { - return EFI_INVALID_PARAMETER; - } - - SdmaAddr = (UINT32)(UINTN)Trb->Data; - Status = SdPeimHcRwMmio (Bar + SD_HC_SDMA_ADDR, FALSE, sizeof (SdmaAddr), &SdmaAddr); - if (EFI_ERROR (Status)) { - return Status; - } - } else if (Trb->Mode == SdAdmaMode) { - AdmaAddr = (UINT64)(UINTN)Trb->AdmaDesc; - Status = SdPeimHcRwMmio (Bar + SD_HC_ADMA_SYS_ADDR, FALSE, sizeof (AdmaAddr), &AdmaAddr); - if (EFI_ERROR (Status)) { - return Status; - } - } - - BlkSize = Trb->BlockSize; - if (Trb->Mode == SdSdmaMode) { - // - // Set SDMA boundary to be 512K bytes. - // - BlkSize |= 0x7000; - } - - Status = SdPeimHcRwMmio (Bar + SD_HC_BLK_SIZE, FALSE, sizeof (BlkSize), &BlkSize); - if (EFI_ERROR (Status)) { - return Status; - } - - BlkCount = 0; - if (Trb->Mode != SdNoData) { - // - // Calcuate Block Count. - // - BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize); - } - Status = SdPeimHcRwMmio (Bar + SD_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount); - if (EFI_ERROR (Status)) { - return Status; - } - - Argument = Packet->SdCmdBlk->CommandArgument; - Status = SdPeimHcRwMmio (Bar + SD_HC_ARG1, FALSE, sizeof (Argument), &Argument); - if (EFI_ERROR (Status)) { - return Status; - } - - TransMode = 0; - if (Trb->Mode != SdNoData) { - if (Trb->Mode != SdPioMode) { - TransMode |= BIT0; - } - if (Trb->Read) { - TransMode |= BIT4; - } - if (BlkCount > 1) { - TransMode |= BIT5 | BIT1; - } - // - // SD memory card needs to use AUTO CMD12 feature. - // - if (BlkCount > 1) { - TransMode |= BIT2; - } - } - - Status = SdPeimHcRwMmio (Bar + SD_HC_TRANS_MOD, FALSE, sizeof (TransMode), &TransMode); - if (EFI_ERROR (Status)) { - return Status; - } - - Cmd = (UINT16)LShiftU64(Packet->SdCmdBlk->CommandIndex, 8); - if (Packet->SdCmdBlk->CommandType == SdCommandTypeAdtc) { - Cmd |= BIT5; - } - // - // Convert ResponseType to value - // - if (Packet->SdCmdBlk->CommandType != SdCommandTypeBc) { - switch (Packet->SdCmdBlk->ResponseType) { - case SdResponseTypeR1: - case SdResponseTypeR5: - case SdResponseTypeR6: - case SdResponseTypeR7: - Cmd |= (BIT1 | BIT3 | BIT4); - break; - case SdResponseTypeR2: - Cmd |= (BIT0 | BIT3); - break; - case SdResponseTypeR3: - case SdResponseTypeR4: - Cmd |= BIT1; - break; - case SdResponseTypeR1b: - case SdResponseTypeR5b: - Cmd |= (BIT0 | BIT1 | BIT3 | BIT4); - break; - default: - ASSERT (FALSE); - break; - } - } - // - // Execute cmd - // - Status = SdPeimHcRwMmio (Bar + SD_HC_COMMAND, FALSE, sizeof (Cmd), &Cmd); - return Status; -} - -/** - Check the TRB execution result. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the SD_TRB instance. - - @retval EFI_SUCCESS The TRB is executed successfully. - @retval EFI_NOT_READY The TRB is not completed for execution. - @retval Others Some erros happen when executing this request. - -**/ -EFI_STATUS -SdPeimCheckTrbResult ( - IN UINTN Bar, - IN SD_TRB *Trb - ) -{ - EFI_STATUS Status; - SD_COMMAND_PACKET *Packet; - UINT16 IntStatus; - UINT32 Response[4]; - UINT32 SdmaAddr; - UINT8 Index; - UINT8 SwReset; - UINT32 PioLength; - - SwReset = 0; - Packet = Trb->Packet; - // - // Check Trb execution result by reading Normal Interrupt Status register. - // - Status = SdPeimHcRwMmio ( - Bar + SD_HC_NOR_INT_STS, - TRUE, - sizeof (IntStatus), - &IntStatus - ); - if (EFI_ERROR (Status)) { - goto Done; - } - // - // Check Transfer Complete bit is set or not. - // - if ((IntStatus & BIT1) == BIT1) { - if ((IntStatus & BIT15) == BIT15) { - // - // Read Error Interrupt Status register to check if the error is - // Data Timeout Error. - // If yes, treat it as success as Transfer Complete has higher - // priority than Data Timeout Error. - // - Status = SdPeimHcRwMmio ( - Bar + SD_HC_ERR_INT_STS, - TRUE, - sizeof (IntStatus), - &IntStatus - ); - if (!EFI_ERROR (Status)) { - if ((IntStatus & BIT4) == BIT4) { - Status = EFI_SUCCESS; - } else { - Status = EFI_DEVICE_ERROR; - } - } - } - - goto Done; - } - // - // Check if there is a error happened during cmd execution. - // If yes, then do error recovery procedure to follow SD Host Controller - // Simplified Spec 3.0 section 3.10.1. - // - if ((IntStatus & BIT15) == BIT15) { - Status = SdPeimHcRwMmio ( - Bar + SD_HC_ERR_INT_STS, - TRUE, - sizeof (IntStatus), - &IntStatus - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - if ((IntStatus & 0x0F) != 0) { - SwReset |= BIT1; - } - if ((IntStatus & 0xF0) != 0) { - SwReset |= BIT2; - } - - Status = SdPeimHcRwMmio ( - Bar + SD_HC_SW_RST, - FALSE, - sizeof (SwReset), - &SwReset - ); - if (EFI_ERROR (Status)) { - goto Done; - } - Status = SdPeimHcWaitMmioSet ( - Bar + SD_HC_SW_RST, - sizeof (SwReset), - 0xFF, - 0, - SD_TIMEOUT - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = EFI_DEVICE_ERROR; - goto Done; - } - // - // Check if DMA interrupt is signalled for the SDMA transfer. - // - if ((Trb->Mode == SdSdmaMode) && ((IntStatus & BIT3) == BIT3)) { - // - // Clear DMA interrupt bit. - // - IntStatus = BIT3; - Status = SdPeimHcRwMmio ( - Bar + SD_HC_NOR_INT_STS, - FALSE, - sizeof (IntStatus), - &IntStatus - ); - if (EFI_ERROR (Status)) { - goto Done; - } - // - // Update SDMA Address register. - // - SdmaAddr = SD_SDMA_ROUND_UP ((UINT32)(UINTN)Trb->Data, SD_SDMA_BOUNDARY); - Status = SdPeimHcRwMmio ( - Bar + SD_HC_SDMA_ADDR, - FALSE, - sizeof (UINT32), - &SdmaAddr - ); - if (EFI_ERROR (Status)) { - goto Done; - } - Trb->Data = (VOID*)(UINTN)SdmaAddr; - } - - if ((Packet->SdCmdBlk->CommandType != SdCommandTypeAdtc) && - (Packet->SdCmdBlk->ResponseType != SdResponseTypeR1b) && - (Packet->SdCmdBlk->ResponseType != SdResponseTypeR5b)) { - if ((IntStatus & BIT0) == BIT0) { - Status = EFI_SUCCESS; - goto Done; - } - } - - if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) { - // - // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode, - // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1. - // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details. - // - if ((IntStatus & BIT5) == BIT5) { - // - // Clear Buffer Read Ready interrupt at first. - // - IntStatus = BIT5; - SdPeimHcRwMmio (Bar + SD_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus); - // - // Read data out from Buffer Port register - // - for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) { - SdPeimHcRwMmio (Bar + SD_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength); - } - Status = EFI_SUCCESS; - goto Done; - } - } - - Status = EFI_NOT_READY; -Done: - // - // Get response data when the cmd is executed successfully. - // - if (!EFI_ERROR (Status)) { - if (Packet->SdCmdBlk->CommandType != SdCommandTypeBc) { - for (Index = 0; Index < 4; Index++) { - Status = SdPeimHcRwMmio ( - Bar + SD_HC_RESPONSE + Index * 4, - TRUE, - sizeof (UINT32), - &Response[Index] - ); - if (EFI_ERROR (Status)) { - SdPeimHcLedOnOff (Bar, FALSE); - return Status; - } - } - CopyMem (Packet->SdStatusBlk, Response, sizeof (Response)); - } - } - - if (Status != EFI_NOT_READY) { - SdPeimHcLedOnOff (Bar, FALSE); - } - - return Status; -} - -/** - Wait for the TRB execution result. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[in] Trb The pointer to the SD_TRB instance. - - @retval EFI_SUCCESS The TRB is executed successfully. - @retval Others Some erros happen when executing this request. - -**/ -EFI_STATUS -SdPeimWaitTrbResult ( - IN UINTN Bar, - IN SD_TRB *Trb - ) -{ - EFI_STATUS Status; - SD_COMMAND_PACKET *Packet; - UINT64 Timeout; - BOOLEAN InfiniteWait; - - Packet = Trb->Packet; - // - // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register - // - Timeout = Packet->Timeout; - if (Timeout == 0) { - InfiniteWait = TRUE; - } else { - InfiniteWait = FALSE; - } - - while (InfiniteWait || (Timeout > 0)) { - // - // Check Trb execution result by reading Normal Interrupt Status register. - // - Status = SdPeimCheckTrbResult (Bar, Trb); - if (Status != EFI_NOT_READY) { - return Status; - } - // - // Stall for 1 microsecond. - // - MicroSecondDelay (1); - - Timeout--; - } - - return EFI_TIMEOUT; -} - -/** - Sends SD command to an SD card that is attached to the SD controller. - - If Packet is successfully sent to the SD card, then EFI_SUCCESS is returned. - - If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned. - - If Slot is not in a valid range for the SD controller, then EFI_INVALID_PARAMETER - is returned. - - If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL, - EFI_INVALID_PARAMETER is returned. - - @param[in] Slot The slot number of the Sd card to send the command to. - @param[in,out] Packet A pointer to the SD command data structure. - - @retval EFI_SUCCESS The SD Command Packet was sent by the host. - @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD - command Packet. - @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid. - @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and - OutDataBuffer are NULL. - @retval EFI_NO_MEDIA SD Device not present in the Slot. - @retval EFI_UNSUPPORTED The command described by the SD Command Packet is not - supported by the host controller. - @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the - limit supported by SD card ( i.e. if the number of bytes - exceed the Last LBA). - -**/ -EFI_STATUS -EFIAPI -SdPeimExecCmd ( - IN SD_PEIM_HC_SLOT *Slot, - IN OUT SD_COMMAND_PACKET *Packet - ) -{ - EFI_STATUS Status; - SD_TRB *Trb; - - if (Packet == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->SdCmdBlk == NULL) || (Packet->SdStatusBlk == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->OutDataBuffer == NULL) && (Packet->OutTransferLength != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->InDataBuffer == NULL) && (Packet->InTransferLength != 0)) { - return EFI_INVALID_PARAMETER; - } - - Trb = SdPeimCreateTrb (Slot, Packet); - if (Trb == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = SdPeimWaitTrbEnv (Slot->SdHcBase, Trb); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = SdPeimExecTrb (Slot->SdHcBase, Trb); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = SdPeimWaitTrbResult (Slot->SdHcBase, Trb); - if (EFI_ERROR (Status)) { - goto Done; - } - -Done: - SdPeimFreeTrb (Trb); - - return Status; -} - -/** - Send command GO_IDLE_STATE to the device to make it go to Idle State. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - - @retval EFI_SUCCESS The SD device is reset correctly. - @retval Others The device reset fails. - -**/ -EFI_STATUS -SdPeimReset ( - IN SD_PEIM_HC_SLOT *Slot - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_GO_IDLE_STATE; - SdCmdBlk.CommandType = SdCommandTypeBc; - SdCmdBlk.ResponseType = 0; - SdCmdBlk.CommandArgument = 0; - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface - condition. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] SupplyVoltage The supplied voltage by the host. - @param[in] CheckPattern The check pattern to be sent to the device. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimVoltageCheck ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT8 SupplyVoltage, - IN UINT8 CheckPattern - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_SEND_IF_COND; - SdCmdBlk.CommandType = SdCommandTypeBcr; - SdCmdBlk.ResponseType = SdResponseTypeR7; - SdCmdBlk.CommandArgument = (SupplyVoltage << 8) | CheckPattern; - - Status = SdPeimExecCmd (Slot, &Packet); - if (!EFI_ERROR (Status)) { - if (SdStatusBlk.Resp0 != SdCmdBlk.CommandArgument) { - return EFI_DEVICE_ERROR; - } - } - - return Status; -} - -/** - Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device. - - Refer to SDIO Simplified Spec 3 Section 3.2 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] VoltageWindow The supply voltage window. - @param[in] S18r The boolean to show if it should switch to 1.8v. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdioSendOpCond ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT32 VoltageWindow, - IN BOOLEAN S18r - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - UINT32 Switch; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SDIO_SEND_OP_COND; - SdCmdBlk.CommandType = SdCommandTypeBcr; - SdCmdBlk.ResponseType = SdResponseTypeR4; - - Switch = S18r ? BIT24 : 0; - - SdCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch; - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SD_SEND_OP_COND to the device to see whether it is SDIO device. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Rca The relative device address of addressed device. - @param[in] VoltageWindow The supply voltage window. - @param[in] S18r The boolean to show if it should switch to 1.8v. - @param[in] Xpc The boolean to show if it should provide 0.36w power control. - @param[in] Hcs The boolean to show if it support host capacity info. - @param[out] Ocr The buffer to store returned OCR register value. - - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSendOpCond ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT16 Rca, - IN UINT32 VoltageWindow, - IN BOOLEAN S18r, - IN BOOLEAN Xpc, - IN BOOLEAN Hcs, - OUT UINT32 *Ocr - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - UINT32 Switch; - UINT32 MaxPower; - UINT32 HostCapacity; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_APP_CMD; - SdCmdBlk.CommandType = SdCommandTypeAc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - SdCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = SdPeimExecCmd (Slot, &Packet); - if (EFI_ERROR (Status)) { - return Status; - } - - SdCmdBlk.CommandIndex = SD_SEND_OP_COND; - SdCmdBlk.CommandType = SdCommandTypeBcr; - SdCmdBlk.ResponseType = SdResponseTypeR3; - - Switch = S18r ? BIT24 : 0; - MaxPower = Xpc ? BIT28 : 0; - HostCapacity = Hcs ? BIT30 : 0; - SdCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch | MaxPower | HostCapacity; - - Status = SdPeimExecCmd (Slot, &Packet); - if (!EFI_ERROR (Status)) { - // - // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. - // - *Ocr = SdStatusBlk.Resp0; - } - - return Status; -} - -/** - Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the - data of their CID registers. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimAllSendCid ( - IN SD_PEIM_HC_SLOT *Slot - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_ALL_SEND_CID; - SdCmdBlk.CommandType = SdCommandTypeBcr; - SdCmdBlk.ResponseType = SdResponseTypeR2; - SdCmdBlk.CommandArgument = 0; - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device - Address (RCA). - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[out] Rca The relative device address to be assigned. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSetRca ( - IN SD_PEIM_HC_SLOT *Slot, - OUT UINT16 *Rca - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_SET_RELATIVE_ADDR; - SdCmdBlk.CommandType = SdCommandTypeBcr; - SdCmdBlk.ResponseType = SdResponseTypeR6; - - Status = SdPeimExecCmd (Slot, &Packet); - if (!EFI_ERROR (Status)) { - *Rca = (UINT16)(SdStatusBlk.Resp0 >> 16); - } - - return Status; -} - -/** - Send command SEND_CSD to the SD device to get the data of the CSD register. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Rca The relative device address of selected device. - @param[out] Csd The buffer to store the content of the CSD register. - Note the caller should ignore the lowest byte of this - buffer as the content of this byte is meaningless even - if the operation succeeds. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimGetCsd ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT16 Rca, - OUT SD_CSD *Csd - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_SEND_CSD; - SdCmdBlk.CommandType = SdCommandTypeAc; - SdCmdBlk.ResponseType = SdResponseTypeR2; - SdCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = SdPeimExecCmd (Slot, &Packet); - if (!EFI_ERROR (Status)) { - // - // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. - // - CopyMem (((UINT8*)Csd) + 1, &SdStatusBlk.Resp0, sizeof (SD_CSD) - 1); - } - - return Status; -} - -/** - Send command SELECT_DESELECT_CARD to the SD device to select/deselect it. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Rca The relative device address of selected device. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSelect ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT16 Rca - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_SELECT_DESELECT_CARD; - SdCmdBlk.CommandType = SdCommandTypeAc; - SdCmdBlk.ResponseType = SdResponseTypeR1b; - SdCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimVoltageSwitch ( - IN SD_PEIM_HC_SLOT *Slot - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_VOLTAGE_SWITCH; - SdCmdBlk.CommandType = SdCommandTypeAc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - SdCmdBlk.CommandArgument = 0; - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SET_BUS_WIDTH to the SD device to set the bus width. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Rca The relative device address of addressed device. - @param[in] BusWidth The bus width to be set, it could be 1 or 4. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSetBusWidth ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT16 Rca, - IN UINT8 BusWidth - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - UINT8 Value; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_APP_CMD; - SdCmdBlk.CommandType = SdCommandTypeAc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - SdCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = SdPeimExecCmd (Slot, &Packet); - if (EFI_ERROR (Status)) { - return Status; - } - - SdCmdBlk.CommandIndex = SD_SET_BUS_WIDTH; - SdCmdBlk.CommandType = SdCommandTypeAc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - - if (BusWidth == 1) { - Value = 0; - } else if (BusWidth == 4) { - Value = 2; - } else { - return EFI_INVALID_PARAMETER; - } - SdCmdBlk.CommandArgument = Value & 0x3; - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SWITCH_FUNC to the SD device to check switchable function or switch card function. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] AccessMode The value for access mode group. - @param[in] CommandSystem The value for command set group. - @param[in] DriveStrength The value for drive length group. - @param[in] PowerLimit The value for power limit group. - @param[in] Mode Switch or check function. - @param[out] SwitchResp The return switch function status. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSwitch ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT8 AccessMode, - IN UINT8 CommandSystem, - IN UINT8 DriveStrength, - IN UINT8 PowerLimit, - IN BOOLEAN Mode, - OUT UINT8 *SwitchResp - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - UINT32 ModeValue; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_SWITCH_FUNC; - SdCmdBlk.CommandType = SdCommandTypeAdtc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - - ModeValue = Mode ? BIT31 : 0; - SdCmdBlk.CommandArgument = (AccessMode & 0xF) | ((PowerLimit & 0xF) << 4) | \ - ((DriveStrength & 0xF) << 8) | ((DriveStrength & 0xF) << 12) | \ - ModeValue; - Packet.InDataBuffer = SwitchResp; - Packet.InTransferLength = 64; - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SEND_STATUS to the addressed SD device to get its status register. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Rca The relative device address of addressed device. - @param[out] DevStatus The returned device status. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSendStatus ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT16 Rca, - OUT UINT32 *DevStatus - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_SEND_STATUS; - SdCmdBlk.CommandType = SdCommandTypeAc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - SdCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = SdPeimExecCmd (Slot, &Packet); - if (!EFI_ERROR (Status)) { - *DevStatus = SdStatusBlk.Resp0; - } - - return Status; -} - -/** - Send command READ_SINGLE_BLOCK/WRITE_SINGLE_BLOCK to the addressed SD device - to read/write the specified number of blocks. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Lba The logical block address of starting access. - @param[in] BlockSize The block size of specified SD device partition. - @param[in] Buffer The pointer to the transfer buffer. - @param[in] BufferSize The size of transfer buffer. - @param[in] IsRead Boolean to show the operation direction. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimRwSingleBlock ( - IN SD_PEIM_HC_SLOT *Slot, - IN EFI_LBA Lba, - IN UINT32 BlockSize, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - // - // Calculate timeout value through the below formula. - // Timeout = (transfer size) / (2MB/s). - // Taking 2MB/s as divisor is because it's the lowest - // transfer speed of class 2. - // - Packet.Timeout = (BufferSize / (2 * 1024 * 1024) + 1) * 1000 * 1000;; - - if (IsRead) { - Packet.InDataBuffer = Buffer; - Packet.InTransferLength = (UINT32)BufferSize; - - SdCmdBlk.CommandIndex = SD_READ_SINGLE_BLOCK; - SdCmdBlk.CommandType = SdCommandTypeAdtc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - } else { - Packet.OutDataBuffer = Buffer; - Packet.OutTransferLength = (UINT32)BufferSize; - - SdCmdBlk.CommandIndex = SD_WRITE_SINGLE_BLOCK; - SdCmdBlk.CommandType = SdCommandTypeAdtc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - } - - if (Slot->SectorAddressing) { - SdCmdBlk.CommandArgument = (UINT32)Lba; - } else { - SdCmdBlk.CommandArgument = (UINT32)MultU64x32 (Lba, BlockSize); - } - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed SD device - to read/write the specified number of blocks. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Lba The logical block address of starting access. - @param[in] BlockSize The block size of specified SD device partition. - @param[in] Buffer The pointer to the transfer buffer. - @param[in] BufferSize The size of transfer buffer. - @param[in] IsRead Boolean to show the operation direction. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimRwMultiBlocks ( - IN SD_PEIM_HC_SLOT *Slot, - IN EFI_LBA Lba, - IN UINT32 BlockSize, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - // - // Calculate timeout value through the below formula. - // Timeout = (transfer size) / (2MB/s). - // Taking 2MB/s as divisor is because it's the lowest - // transfer speed of class 2. - // - Packet.Timeout = (BufferSize / (2 * 1024 * 1024) + 1) * 1000 * 1000;; - - if (IsRead) { - Packet.InDataBuffer = Buffer; - Packet.InTransferLength = (UINT32)BufferSize; - - SdCmdBlk.CommandIndex = SD_READ_MULTIPLE_BLOCK; - SdCmdBlk.CommandType = SdCommandTypeAdtc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - } else { - Packet.OutDataBuffer = Buffer; - Packet.OutTransferLength = (UINT32)BufferSize; - - SdCmdBlk.CommandIndex = SD_WRITE_MULTIPLE_BLOCK; - SdCmdBlk.CommandType = SdCommandTypeAdtc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - } - - if (Slot->SectorAddressing) { - SdCmdBlk.CommandArgument = (UINT32)Lba; - } else { - SdCmdBlk.CommandArgument = (UINT32)MultU64x32 (Lba, BlockSize); - } - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Send command SEND_TUNING_BLOCK to the SD device for SDR104/SDR50 optimal sampling point - detection. - - It may be sent up to 40 times until the host finishes the tuning procedure. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSendTuningBlk ( - IN SD_PEIM_HC_SLOT *Slot - ) -{ - SD_COMMAND_BLOCK SdCmdBlk; - SD_STATUS_BLOCK SdStatusBlk; - SD_COMMAND_PACKET Packet; - EFI_STATUS Status; - UINT8 TuningBlock[64]; - - ZeroMem (&SdCmdBlk, sizeof (SdCmdBlk)); - ZeroMem (&SdStatusBlk, sizeof (SdStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - - Packet.SdCmdBlk = &SdCmdBlk; - Packet.SdStatusBlk = &SdStatusBlk; - Packet.Timeout = SD_TIMEOUT; - - SdCmdBlk.CommandIndex = SD_SEND_TUNING_BLOCK; - SdCmdBlk.CommandType = SdCommandTypeAdtc; - SdCmdBlk.ResponseType = SdResponseTypeR1; - SdCmdBlk.CommandArgument = 0; - - Packet.InDataBuffer = TuningBlock; - Packet.InTransferLength = sizeof (TuningBlock); - - Status = SdPeimExecCmd (Slot, &Packet); - - return Status; -} - -/** - Tunning the sampling point of SDR104 or SDR50 bus speed mode. - - Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the - tuning procedure. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and SD Host Controller - Simplified Spec 3.0 Figure 2-29 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimTuningClock ( - IN SD_PEIM_HC_SLOT *Slot - ) -{ - EFI_STATUS Status; - UINT8 HostCtrl2; - UINT8 Retry; - - // - // Notify the host that the sampling clock tuning procedure starts. - // - HostCtrl2 = BIT6; - Status = SdPeimHcOrMmio (Slot->SdHcBase + SD_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Ask the device to send a sequence of tuning blocks till the tuning procedure is done. - // - Retry = 0; - do { - Status = SdPeimSendTuningBlk (Slot); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdPeimHcRwMmio (Slot->SdHcBase + SD_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((HostCtrl2 & (BIT6 | BIT7)) == 0) { - break; - } - - if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) { - return EFI_SUCCESS; - } - } while (++Retry < 40); - - DEBUG ((EFI_D_ERROR, "SdPeimTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2)); - // - // Abort the tuning procedure and reset the tuning circuit. - // - HostCtrl2 = (UINT8)~(BIT6 | BIT7); - Status = SdPeimHcAndMmio (Slot->SdHcBase + SD_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - return EFI_DEVICE_ERROR; -} - -/** - Switch the bus width to specified width. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and - SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Rca The relative device address to be assigned. - @param[in] BusWidth The bus width to be set, it could be 4 or 8. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSwitchBusWidth ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT16 Rca, - IN UINT8 BusWidth - ) -{ - EFI_STATUS Status; - UINT32 DevStatus; - - Status = SdPeimSetBusWidth (Slot, Rca, BusWidth); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdPeimSendStatus (Slot, Rca, &DevStatus); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Check the switch operation is really successful or not. - // - if ((DevStatus >> 16) != 0) { - return EFI_DEVICE_ERROR; - } - - Status = SdPeimHcSetBusWidth (Slot->SdHcBase, BusWidth); - - return Status; -} - -/** - Switch the high speed timing according to request. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and - SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Rca The relative device address to be assigned. - @param[in] S18a The boolean to show if it's a UHS-I SD card. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSetBusMode ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT16 Rca, - IN BOOLEAN S18a - ) -{ - EFI_STATUS Status; - SD_HC_SLOT_CAP Capability; - UINT32 ClockFreq; - UINT8 BusWidth; - UINT8 AccessMode; - UINT8 HostCtrl1; - UINT8 HostCtrl2; - UINT8 SwitchResp[64]; - - Status = SdPeimGetCsd (Slot, Rca, &Slot->Csd); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimGetCsd fails with %r\n", Status)); - return Status; - } - - Status = SdPeimHcGetCapability (Slot->SdHcBase, &Capability); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdPeimSelect (Slot, Rca); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimSelect fails with %r\n", Status)); - return Status; - } - - BusWidth = 4; - Status = SdPeimSwitchBusWidth (Slot, Rca, BusWidth); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimSwitchBusWidth fails with %r\n", Status)); - return Status; - } - - // - // Get the supported bus speed from SWITCH cmd return data group #1. - // - ZeroMem (SwitchResp, sizeof (SwitchResp)); - Status = SdPeimSwitch (Slot, 0xF, 0xF, 0xF, 0xF, FALSE, SwitchResp); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Calculate supported bus speed/bus width/clock frequency by host and device capability. - // - ClockFreq = 0; - if (S18a && (Capability.Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) { - ClockFreq = 208; - AccessMode = 3; - } else if (S18a && (Capability.Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) { - ClockFreq = 100; - AccessMode = 2; - } else if (S18a && (Capability.Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) { - ClockFreq = 50; - AccessMode = 4; - } else if ((SwitchResp[13] & BIT1) != 0) { - ClockFreq = 50; - AccessMode = 1; - } else { - ClockFreq = 25; - AccessMode = 0; - } - - DEBUG ((EFI_D_INFO, "SdPeimSetBusMode: AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth)); - - Status = SdPeimSwitch (Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimSwitch fails with %r\n", Status)); - return Status; - } - - if ((SwitchResp[16] & 0xF) != AccessMode) { - DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimSwitch to AccessMode %d ClockFreq %d BusWidth %d fails! The Switch response is 0x%1x\n", AccessMode, ClockFreq, BusWidth, SwitchResp[16] & 0xF)); - return EFI_DEVICE_ERROR; - } - // - // Set to Hight Speed timing - // - if (AccessMode == 1) { - HostCtrl1 = BIT2; - Status = SdPeimHcOrMmio (Slot->SdHcBase + SD_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - } - - HostCtrl2 = (UINT8)~0x7; - Status = SdPeimHcAndMmio (Slot->SdHcBase + SD_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - HostCtrl2 = AccessMode; - Status = SdPeimHcOrMmio (Slot->SdHcBase + SD_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdPeimHcClockSupply (Slot->SdHcBase, ClockFreq * 1000); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimHcClockSupply %r\n", Status)); - return Status; - } - - if ((AccessMode == 3) || ((AccessMode == 2) && (Capability.TuningSDR50 != 0))) { - Status = SdPeimTuningClock (Slot); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimSetBusMode: SdPeimTuningClock fails with %r\n", Status)); - return Status; - } - } - - DEBUG ((EFI_D_INFO, "SdPeimSetBusMode: SdPeimSetBusMode %r\n", Status)); - - return Status; -} - -/** - Execute SD device identification procedure. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - - @retval EFI_SUCCESS There is a SD card. - @retval Others There is not a SD card. - -**/ -EFI_STATUS -SdPeimIdentification ( - IN SD_PEIM_HC_SLOT *Slot - ) -{ - EFI_STATUS Status; - UINT32 Ocr; - UINT16 Rca; - BOOLEAN Xpc; - BOOLEAN S18r; - UINT64 MaxCurrent; - UINT64 Current; - UINT16 ControllerVer; - UINT8 PowerCtrl; - UINT32 PresentState; - UINT8 HostCtrl2; - SD_HC_SLOT_CAP Capability; - UINTN Retry; - // - // 1. Send Cmd0 to the device - // - Status = SdPeimReset (Slot); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: Executing Cmd0 fails with %r\n", Status)); - return Status; - } - // - // 2. Send Cmd8 to the device - // - Status = SdPeimVoltageCheck (Slot, 0x1, 0xFF); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: Executing Cmd8 fails with %r\n", Status)); - return Status; - } - // - // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register. - // - Status = SdioSendOpCond (Slot, 0, FALSE); - if (!EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: Found SDIO device, ignore it as we don't support\n")); - return EFI_DEVICE_ERROR; - } - // - // 4. Send Acmd41 with voltage window 0 to the device - // - Status = SdPeimSendOpCond (Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: Executing SdPeimSendOpCond fails with %r\n", Status)); - return EFI_DEVICE_ERROR; - } - - Status = SdPeimHcGetCapability (Slot->SdHcBase, &Capability); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdPeimHcRwMmio (Slot->SdHcBase + SD_HC_MAX_CURRENT_CAP, TRUE, sizeof (Current), &Current); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Capability.Voltage33 != 0) { - // - // Support 3.3V - // - MaxCurrent = ((UINT32)Current & 0xFF) * 4; - } else if (Capability.Voltage30 != 0) { - // - // Support 3.0V - // - MaxCurrent = (((UINT32)Current >> 8) & 0xFF) * 4; - } else if (Capability.Voltage18 != 0) { - // - // Support 1.8V - // - MaxCurrent = (((UINT32)Current >> 16) & 0xFF) * 4; - } else { - ASSERT (FALSE); - return EFI_DEVICE_ERROR; - } - - if (MaxCurrent >= 150) { - Xpc = TRUE; - } else { - Xpc = FALSE; - } - - Status = SdPeimHcRwMmio (Slot->SdHcBase + SD_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((ControllerVer & 0xFF) == 2) { - S18r = TRUE; - } else if (((ControllerVer & 0xFF) == 0) || ((ControllerVer & 0xFF) == 1)) { - S18r = FALSE; - } else { - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } - // - // 5. Repeatly send Acmd41 with supply voltage window to the device. - // Note here we only support the cards complied with SD physical - // layer simplified spec version 2.0 and version 3.0 and above. - // - Ocr = 0; - Retry = 0; - do { - Status = SdPeimSendOpCond (Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: SdPeimSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc)); - return EFI_DEVICE_ERROR; - } - - if (Retry++ == 100) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: SdPeimSendOpCond fails too many times\n")); - return EFI_DEVICE_ERROR; - } - MicroSecondDelay (10 * 1000); - } while ((Ocr & BIT31) == 0); - - // - // 6. If the S18a bit is set and the Host Controller supports 1.8V signaling - // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the - // Capabilities register), switch its voltage to 1.8V. - // - if ((Capability.Sdr50 != 0 || - Capability.Sdr104 != 0 || - Capability.Ddr50 != 0) && - ((Ocr & BIT24) != 0)) { - Status = SdPeimVoltageSwitch (Slot); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: Executing SdPeimVoltageSwitch fails with %r\n", Status)); - Status = EFI_DEVICE_ERROR; - goto Error; - } else { - Status = SdPeimHcStopClock (Slot->SdHcBase); - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Error; - } - - SdPeimHcRwMmio (Slot->SdHcBase + SD_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState); - if (((PresentState >> 20) & 0xF) != 0) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState)); - Status = EFI_DEVICE_ERROR; - goto Error; - } - HostCtrl2 = BIT3; - SdPeimHcOrMmio (Slot->SdHcBase + SD_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - - MicroSecondDelay (5000); - - SdPeimHcRwMmio (Slot->SdHcBase + SD_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2); - if ((HostCtrl2 & BIT3) == 0) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2)); - Status = EFI_DEVICE_ERROR; - goto Error; - } - - SdPeimHcInitClockFreq (Slot->SdHcBase); - - MicroSecondDelay (1000); - - SdPeimHcRwMmio (Slot->SdHcBase + SD_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState); - if (((PresentState >> 20) & 0xF) != 0xF) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState)); - Status = EFI_DEVICE_ERROR; - goto Error; - } - } - DEBUG ((EFI_D_INFO, "SdPeimIdentification: Switch to 1.8v signal voltage success\n")); - } - - Status = SdPeimAllSendCid (Slot); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: Executing SdPeimAllSendCid fails with %r\n", Status)); - return Status; - } - - Status = SdPeimSetRca (Slot, &Rca); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SdPeimIdentification: Executing SdPeimSetRca fails with %r\n", Status)); - return Status; - } - // - // Enter Data Tranfer Mode. - // - DEBUG ((EFI_D_INFO, "Found a SD device at slot [%d]\n", Slot)); - - Status = SdPeimSetBusMode (Slot, Rca, ((Ocr & BIT24) != 0)); - - return Status; - -Error: - // - // Set SD Bus Power = 0 - // - PowerCtrl = (UINT8)~BIT0; - Status = SdPeimHcAndMmio (Slot->SdHcBase + SD_HC_POWER_CTRL, sizeof (PowerCtrl), &PowerCtrl); - return EFI_DEVICE_ERROR; -} diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.h b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.h deleted file mode 100644 index b7c0dbc9f3..0000000000 --- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.h +++ /dev/null @@ -1,356 +0,0 @@ -/** @file - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SD_HCI_H_ -#define _SD_HCI_H_ - -// -// SD Host Controller MMIO Register Offset -// -#define SD_HC_SDMA_ADDR 0x00 -#define SD_HC_ARG2 0x00 -#define SD_HC_BLK_SIZE 0x04 -#define SD_HC_BLK_COUNT 0x06 -#define SD_HC_ARG1 0x08 -#define SD_HC_TRANS_MOD 0x0C -#define SD_HC_COMMAND 0x0E -#define SD_HC_RESPONSE 0x10 -#define SD_HC_BUF_DAT_PORT 0x20 -#define SD_HC_PRESENT_STATE 0x24 -#define SD_HC_HOST_CTRL1 0x28 -#define SD_HC_POWER_CTRL 0x29 -#define SD_HC_BLK_GAP_CTRL 0x2A -#define SD_HC_WAKEUP_CTRL 0x2B -#define SD_HC_CLOCK_CTRL 0x2C -#define SD_HC_TIMEOUT_CTRL 0x2E -#define SD_HC_SW_RST 0x2F -#define SD_HC_NOR_INT_STS 0x30 -#define SD_HC_ERR_INT_STS 0x32 -#define SD_HC_NOR_INT_STS_EN 0x34 -#define SD_HC_ERR_INT_STS_EN 0x36 -#define SD_HC_NOR_INT_SIG_EN 0x38 -#define SD_HC_ERR_INT_SIG_EN 0x3A -#define SD_HC_AUTO_CMD_ERR_STS 0x3C -#define SD_HC_HOST_CTRL2 0x3E -#define SD_HC_CAP 0x40 -#define SD_HC_MAX_CURRENT_CAP 0x48 -#define SD_HC_FORCE_EVT_AUTO_CMD 0x50 -#define SD_HC_FORCE_EVT_ERR_INT 0x52 -#define SD_HC_ADMA_ERR_STS 0x54 -#define SD_HC_ADMA_SYS_ADDR 0x58 -#define SD_HC_PRESET_VAL 0x60 -#define SD_HC_SHARED_BUS_CTRL 0xE0 -#define SD_HC_SLOT_INT_STS 0xFC -#define SD_HC_CTRL_VER 0xFE - -// -// The transfer modes supported by SD Host Controller -// Simplified Spec 3.0 Table 1-2 -// -typedef enum { - SdNoData, - SdPioMode, - SdSdmaMode, - SdAdmaMode -} SD_HC_TRANSFER_MODE; - -// -// The maximum data length of each descriptor line -// -#define ADMA_MAX_DATA_PER_LINE 0x10000 -#define SD_SDMA_BOUNDARY 512 * 1024 -#define SD_SDMA_ROUND_UP(x, n) (((x) + n) & ~(n - 1)) - -typedef enum { - SdCommandTypeBc, // Broadcast commands, no response - SdCommandTypeBcr, // Broadcast commands with response - SdCommandTypeAc, // Addressed(point-to-point) commands - SdCommandTypeAdtc // Addressed(point-to-point) data transfer commands -} SD_COMMAND_TYPE; - -typedef enum { - SdResponseTypeR1, - SdResponseTypeR1b, - SdResponseTypeR2, - SdResponseTypeR3, - SdResponseTypeR4, - SdResponseTypeR5, - SdResponseTypeR5b, - SdResponseTypeR6, - SdResponseTypeR7 -} SD_RESPONSE_TYPE; - -typedef struct _SD_COMMAND_BLOCK { - UINT16 CommandIndex; - UINT32 CommandArgument; - UINT32 CommandType; // One of the SD_COMMAND_TYPE values - UINT32 ResponseType; // One of the SD_RESPONSE_TYPE values -} SD_COMMAND_BLOCK; - -typedef struct _SD_STATUS_BLOCK { - UINT32 Resp0; - UINT32 Resp1; - UINT32 Resp2; - UINT32 Resp3; -} SD_STATUS_BLOCK; - -typedef struct _SD_COMMAND_PACKET { - UINT64 Timeout; - SD_COMMAND_BLOCK *SdCmdBlk; - SD_STATUS_BLOCK *SdStatusBlk; - VOID *InDataBuffer; - VOID *OutDataBuffer; - UINT32 InTransferLength; - UINT32 OutTransferLength; -} SD_COMMAND_PACKET; - -#pragma pack(1) - -typedef struct { - UINT32 Valid:1; - UINT32 End:1; - UINT32 Int:1; - UINT32 Reserved:1; - UINT32 Act:2; - UINT32 Reserved1:10; - UINT32 Length:16; - UINT32 Address; -} SD_HC_ADMA_DESC_LINE; - -typedef struct { - UINT32 TimeoutFreq:6; // bit 0:5 - UINT32 Reserved:1; // bit 6 - UINT32 TimeoutUnit:1; // bit 7 - UINT32 BaseClkFreq:8; // bit 8:15 - UINT32 MaxBlkLen:2; // bit 16:17 - UINT32 BusWidth8:1; // bit 18 - UINT32 Adma2:1; // bit 19 - UINT32 Reserved2:1; // bit 20 - UINT32 HighSpeed:1; // bit 21 - UINT32 Sdma:1; // bit 22 - UINT32 SuspRes:1; // bit 23 - UINT32 Voltage33:1; // bit 24 - UINT32 Voltage30:1; // bit 25 - UINT32 Voltage18:1; // bit 26 - UINT32 Reserved3:1; // bit 27 - UINT32 SysBus64:1; // bit 28 - UINT32 AsyncInt:1; // bit 29 - UINT32 SlotType:2; // bit 30:31 - UINT32 Sdr50:1; // bit 32 - UINT32 Sdr104:1; // bit 33 - UINT32 Ddr50:1; // bit 34 - UINT32 Reserved4:1; // bit 35 - UINT32 DriverTypeA:1; // bit 36 - UINT32 DriverTypeC:1; // bit 37 - UINT32 DriverTypeD:1; // bit 38 - UINT32 DriverType4:1; // bit 39 - UINT32 TimerCount:4; // bit 40:43 - UINT32 Reserved5:1; // bit 44 - UINT32 TuningSDR50:1; // bit 45 - UINT32 RetuningMod:2; // bit 46:47 - UINT32 ClkMultiplier:8; // bit 48:55 - UINT32 Reserved6:7; // bit 56:62 - UINT32 Hs400:1; // bit 63 -} SD_HC_SLOT_CAP; - -#pragma pack() - -/** - Software reset the specified SD host controller and enable all interrupts. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The software reset executes successfully. - @retval Others The software reset fails. - -**/ -EFI_STATUS -SdPeimHcReset ( - IN UINTN Bar - ); - -/** - Set all interrupt status bits in Normal and Error Interrupt Status Enable - register. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The operation executes successfully. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimHcEnableInterrupt ( - IN UINTN Bar - ); - -/** - Get the capability data from the specified slot. - - @param[in] Bar The mmio base address of the slot to be accessed. - @param[out] Capability The buffer to store the capability data. - - @retval EFI_SUCCESS The operation executes successfully. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimHcGetCapability ( - IN UINTN Bar, - OUT SD_HC_SLOT_CAP *Capability - ); - -/** - Detect whether there is a SD card attached at the specified SD host controller - slot. - - Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS There is a SD card attached. - @retval EFI_NO_MEDIA There is not a SD card attached. - @retval Others The detection fails. - -**/ -EFI_STATUS -SdPeimHcCardDetect ( - IN UINTN Bar - ); - -/** - Initial SD host controller with lowest clock frequency, max power and max timeout value - at initialization. - - @param[in] Bar The mmio base address of the slot to be accessed. - - @retval EFI_SUCCESS The host controller is initialized successfully. - @retval Others The host controller isn't initialized successfully. - -**/ -EFI_STATUS -SdPeimHcInitHost ( - IN UINTN Bar - ); - -/** - Send command SWITCH_FUNC to the SD device to check switchable function or switch card function. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] AccessMode The value for access mode group. - @param[in] CommandSystem The value for command set group. - @param[in] DriveStrength The value for drive length group. - @param[in] PowerLimit The value for power limit group. - @param[in] Mode Switch or check function. - @param[out] SwitchResp The return switch function status. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimSwitch ( - IN SD_PEIM_HC_SLOT *Slot, - IN UINT8 AccessMode, - IN UINT8 CommandSystem, - IN UINT8 DriveStrength, - IN UINT8 PowerLimit, - IN BOOLEAN Mode, - OUT UINT8 *SwitchResp - ); - -/** - Send command READ_SINGLE_BLOCK/WRITE_SINGLE_BLOCK to the addressed SD device - to read/write the specified number of blocks. - - Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. - - @param[in] Slot The slot number of the SD card to send the command to. - @param[in] Lba The logical block address of starting access. - @param[in] BlockSize The block size of specified SD device partition. - @param[in] Buffer The pointer to the transfer buffer. - @param[in] BufferSize The size of transfer buffer. - @param[in] IsRead Boolean to show the operation direction. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimRwSingleBlock ( - IN SD_PEIM_HC_SLOT *Slot, - IN EFI_LBA Lba, - IN UINT32 BlockSize, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead - ); - -/** - Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed SD device - to read/write the specified number of blocks. - - Refer to SD Electrical Standard Spec 5.1 Section 6.10.4 for details. - - @param[in] Slot The slot number of the Sd card to send the command to. - @param[in] Lba The logical block address of starting access. - @param[in] BlockSize The block size of specified SD device partition. - @param[in] Buffer The pointer to the transfer buffer. - @param[in] BufferSize The size of transfer buffer. - @param[in] IsRead Boolean to show the operation direction. - - @retval EFI_SUCCESS The operation is done correctly. - @retval Others The operation fails. - -**/ -EFI_STATUS -SdPeimRwMultiBlocks ( - IN SD_PEIM_HC_SLOT *Slot, - IN EFI_LBA Lba, - IN UINT32 BlockSize, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead - ); - -/** - Execute SD device identification procedure. - - Refer to SD Electrical Standard Spec 5.1 Section 6.4 for details. - - @param[in] Slot The slot number of the Sd card to send the command to. - - @retval EFI_SUCCESS There is a SD card. - @retval Others There is not a SD card. - -**/ -EFI_STATUS -SdPeimIdentification ( - IN SD_PEIM_HC_SLOT *Slot - ); - -/** - Free the resource used by the TRB. - - @param[in] Trb The pointer to the SD_TRB instance. - -**/ -VOID -SdPeimFreeTrb ( - IN SD_TRB *Trb - ); - -#endif - diff --git a/MdeModulePkg/Bus/Sd/SdDxe/ComponentName.c b/MdeModulePkg/Bus/Sd/SdDxe/ComponentName.c deleted file mode 100644 index 246378381f..0000000000 --- a/MdeModulePkg/Bus/Sd/SdDxe/ComponentName.c +++ /dev/null @@ -1,240 +0,0 @@ -/** @file - UEFI Component Name(2) protocol implementation for SdDxe driver. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "SdDxe.h" - -// -// Driver name table -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSdDxeDriverNameTable[] = { - { "eng;en", L"Edkii Sd Memory Card Device Driver" }, - { NULL , NULL } -}; - -// -// Controller name table -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSdDxeControllerNameTable[] = { - { "eng;en", L"Edkii Sd Host Controller" }, - { NULL , NULL } -}; - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gSdDxeComponentName = { - SdDxeComponentNameGetDriverName, - SdDxeComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gSdDxeComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SdDxeComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) SdDxeComponentNameGetControllerName, - "en" -}; - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -SdDxeComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mSdDxeDriverNameTable, - DriverName, - (BOOLEAN)(This == &gSdDxeComponentName) - ); - -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -SdDxeComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - SD_DEVICE *Device; - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - - // - // Make sure this driver is currently managing ControllHandle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gSdDxeDriverBinding.DriverBindingHandle, - &gEfiSdMmcPassThruProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - ControllerNameTable = mSdDxeControllerNameTable; - if (ChildHandle != NULL) { - Status = EfiTestChildHandle ( - ControllerHandle, - ChildHandle, - &gEfiSdMmcPassThruProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Get the child context - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo, - gSdDxeDriverBinding.DriverBindingHandle, - ChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Device = SD_DEVICE_DATA_FROM_BLKIO (BlockIo); - ControllerNameTable = Device->ControllerNameTable; - } - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - ControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gSdDxeComponentName) - ); -} - diff --git a/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c b/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c deleted file mode 100644 index 516c3e7042..0000000000 --- a/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c +++ /dev/null @@ -1,1379 +0,0 @@ -/** @file - The helper functions for BlockIo and BlockIo2 protocol. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "SdDxe.h" - -/** - Nonblocking I/O callback funtion when the event is signaled. - - @param[in] Event The Event this notify function registered to. - @param[in] Context Pointer to the context data registered to the - Event. - -**/ -VOID -EFIAPI -AsyncIoCallback ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - SD_REQUEST *Request; - - gBS->CloseEvent (Event); - - Request = (SD_REQUEST *) Context; - - DEBUG_CODE_BEGIN (); - DEBUG ((EFI_D_INFO, "Sd Async Request: CmdIndex[%d] Arg[%08x] %r\n", - Request->SdMmcCmdBlk.CommandIndex, Request->SdMmcCmdBlk.CommandArgument, - Request->Packet.TransactionStatus)); - DEBUG_CODE_END (); - - if (EFI_ERROR (Request->Packet.TransactionStatus)) { - Request->Token->TransactionStatus = Request->Packet.TransactionStatus; - } - - RemoveEntryList (&Request->Link); - - if (Request->IsEnd) { - gBS->SignalEvent (Request->Token->Event); - } - - FreePool (Request); -} - -/** - Send command SET_RELATIVE_ADDRESS to the device to set the device address. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[out] Rca The relative device address to assign. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdSetRca ( - IN SD_DEVICE *Device, - OUT UINT16 *Rca - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = SD_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = SD_SET_RELATIVE_ADDR; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR6; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - if (!EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, "Set RCA succeeds with Resp0 = 0x%x\n", SdMmcStatusBlk.Resp0)); - *Rca = (UINT16)(SdMmcStatusBlk.Resp0 >> 16); - } - - return Status; -} - -/** - Send command SELECT to the device to select/deselect the device. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Rca The relative device address to use. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdSelect ( - IN SD_DEVICE *Device, - IN UINT16 Rca - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = SD_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = SD_SELECT_DESELECT_CARD; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - if (Rca != 0) { - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b; - } - SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - - return Status; -} - -/** - Send command SEND_STATUS to the device to get device status. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] DevStatus The buffer to store the device status. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdSendStatus ( - IN SD_DEVICE *Device, - IN UINT16 Rca, - OUT UINT32 *DevStatus - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = SD_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = SD_SEND_STATUS; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - if (!EFI_ERROR (Status)) { - CopyMem (DevStatus, &SdMmcStatusBlk.Resp0, sizeof (UINT32)); - } - return Status; -} - -/** - Send command SEND_CSD to the device to get the CSD register data. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] Csd The buffer to store the SD_CSD register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdGetCsd ( - IN SD_DEVICE *Device, - IN UINT16 Rca, - OUT SD_CSD *Csd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - ZeroMem (Csd, sizeof (SD_CSD)); - - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = SD_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = SD_SEND_CSD; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2; - SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - - if (!EFI_ERROR (Status)) { - // - // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. - // - CopyMem (((UINT8*)Csd) + 1, &SdMmcStatusBlk.Resp0, sizeof (SD_CSD) - 1); - } - - return Status; -} - -/** - Send command SEND_CID to the device to get the CID register data. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] Cid The buffer to store the SD_CID register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdGetCid ( - IN SD_DEVICE *Device, - IN UINT16 Rca, - OUT SD_CID *Cid - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - PassThru = Device->Private->PassThru; - - ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); - ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); - ZeroMem (&Packet, sizeof (Packet)); - ZeroMem (Cid, sizeof (SD_CID)); - - Packet.SdMmcCmdBlk = &SdMmcCmdBlk; - Packet.SdMmcStatusBlk = &SdMmcStatusBlk; - Packet.Timeout = SD_GENERIC_TIMEOUT; - - SdMmcCmdBlk.CommandIndex = SD_SEND_CID; - SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2; - SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; - - Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL); - - if (!EFI_ERROR (Status)) { - // - // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. - // - CopyMem (((UINT8*)Cid) + 1, &SdMmcStatusBlk.Resp0, sizeof (SD_CID) - 1); - } - - return Status; -} - -/** - Read/write single block through sync or async I/O request. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Lba The starting logical block address to be read/written. - The caller is responsible for reading/writing to only - legitimate locations. - @param[in] Buffer A pointer to the destination/source buffer for the data. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] IsRead Indicates it is a read or write operation. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdRwSingleBlock ( - IN SD_DEVICE *Device, - IN EFI_LBA Lba, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - SD_REQUEST *RwSingleBlkReq; - EFI_TPL OldTpl; - - RwSingleBlkReq = NULL; - PassThru = Device->Private->PassThru; - - RwSingleBlkReq = AllocateZeroPool (sizeof (SD_REQUEST)); - if (RwSingleBlkReq == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - RwSingleBlkReq->Signature = SD_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Device->Queue, &RwSingleBlkReq->Link); - gBS->RestoreTPL (OldTpl); - RwSingleBlkReq->Packet.SdMmcCmdBlk = &RwSingleBlkReq->SdMmcCmdBlk; - RwSingleBlkReq->Packet.SdMmcStatusBlk = &RwSingleBlkReq->SdMmcStatusBlk; - // - // Calculate timeout value through the below formula. - // Timeout = (transfer size) / (2MB/s). - // Taking 2MB/s as divisor as it's the lowest transfer speed - // above class 2. - // Refer to SD Physical Layer Simplified spec section 3.4 for details. - // - RwSingleBlkReq->Packet.Timeout = (BufferSize / (2 * 1024 * 1024) + 1) * 1000 * 1000; - - if (IsRead) { - RwSingleBlkReq->Packet.InDataBuffer = Buffer; - RwSingleBlkReq->Packet.InTransferLength = (UINT32)BufferSize; - - RwSingleBlkReq->SdMmcCmdBlk.CommandIndex = SD_READ_SINGLE_BLOCK; - RwSingleBlkReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - RwSingleBlkReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - } else { - RwSingleBlkReq->Packet.OutDataBuffer = Buffer; - RwSingleBlkReq->Packet.OutTransferLength = (UINT32)BufferSize; - - RwSingleBlkReq->SdMmcCmdBlk.CommandIndex = SD_WRITE_SINGLE_BLOCK; - RwSingleBlkReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - RwSingleBlkReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - } - - if (Device->SectorAddressing) { - RwSingleBlkReq->SdMmcCmdBlk.CommandArgument = (UINT32)Lba; - } else { - RwSingleBlkReq->SdMmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (Lba, Device->BlockMedia.BlockSize); - } - - RwSingleBlkReq->IsEnd = IsEnd; - RwSingleBlkReq->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - RwSingleBlkReq, - &RwSingleBlkReq->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - RwSingleBlkReq->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &RwSingleBlkReq->Packet, RwSingleBlkReq->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (RwSingleBlkReq != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&RwSingleBlkReq->Link); - gBS->RestoreTPL (OldTpl); - if (RwSingleBlkReq->Event != NULL) { - gBS->CloseEvent (RwSingleBlkReq->Event); - } - FreePool (RwSingleBlkReq); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (RwSingleBlkReq != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&RwSingleBlkReq->Link); - gBS->RestoreTPL (OldTpl); - FreePool (RwSingleBlkReq); - } - } - - return Status; -} - -/** - Read/write multiple blocks through sync or async I/O request. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Lba The starting logical block address to be read/written. - The caller is responsible for reading/writing to only - legitimate locations. - @param[in] Buffer A pointer to the destination/source buffer for the data. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] IsRead Indicates it is a read or write operation. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdRwMultiBlocks ( - IN SD_DEVICE *Device, - IN EFI_LBA Lba, - IN VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - SD_REQUEST *RwMultiBlkReq; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_TPL OldTpl; - - RwMultiBlkReq = NULL; - - PassThru = Device->Private->PassThru; - - RwMultiBlkReq = AllocateZeroPool (sizeof (SD_REQUEST)); - if (RwMultiBlkReq == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - RwMultiBlkReq->Signature = SD_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Device->Queue, &RwMultiBlkReq->Link); - gBS->RestoreTPL (OldTpl); - RwMultiBlkReq->Packet.SdMmcCmdBlk = &RwMultiBlkReq->SdMmcCmdBlk; - RwMultiBlkReq->Packet.SdMmcStatusBlk = &RwMultiBlkReq->SdMmcStatusBlk; - // - // Calculate timeout value through the below formula. - // Timeout = (transfer size) / (2MB/s). - // Taking 2MB/s as divisor as it's the lowest transfer speed - // above class 2. - // Refer to SD Physical Layer Simplified spec section 3.4 for details. - // - RwMultiBlkReq->Packet.Timeout = (BufferSize / (2 * 1024 * 1024) + 1) * 1000 * 1000; - - if (IsRead) { - RwMultiBlkReq->Packet.InDataBuffer = Buffer; - RwMultiBlkReq->Packet.InTransferLength = (UINT32)BufferSize; - - RwMultiBlkReq->SdMmcCmdBlk.CommandIndex = SD_READ_MULTIPLE_BLOCK; - RwMultiBlkReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - RwMultiBlkReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - } else { - RwMultiBlkReq->Packet.OutDataBuffer = Buffer; - RwMultiBlkReq->Packet.OutTransferLength = (UINT32)BufferSize; - - RwMultiBlkReq->SdMmcCmdBlk.CommandIndex = SD_WRITE_MULTIPLE_BLOCK; - RwMultiBlkReq->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; - RwMultiBlkReq->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - } - - if (Device->SectorAddressing) { - RwMultiBlkReq->SdMmcCmdBlk.CommandArgument = (UINT32)Lba; - } else { - RwMultiBlkReq->SdMmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (Lba, Device->BlockMedia.BlockSize); - } - - RwMultiBlkReq->IsEnd = IsEnd; - RwMultiBlkReq->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - RwMultiBlkReq, - &RwMultiBlkReq->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - RwMultiBlkReq->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &RwMultiBlkReq->Packet, RwMultiBlkReq->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (RwMultiBlkReq != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&RwMultiBlkReq->Link); - gBS->RestoreTPL (OldTpl); - if (RwMultiBlkReq->Event != NULL) { - gBS->CloseEvent (RwMultiBlkReq->Event); - } - FreePool (RwMultiBlkReq); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (RwMultiBlkReq != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&RwMultiBlkReq->Link); - gBS->RestoreTPL (OldTpl); - FreePool (RwMultiBlkReq); - } - } - - return Status; -} - -/** - This function transfers data from/to the sd memory card device. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] MediaId The media ID that the read/write request is for. - @param[in] Lba The starting logical block address to be read/written. - The caller is responsible for reading/writing to only - legitimate locations. - @param[in, out] Buffer A pointer to the destination/source buffer for the data. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] IsRead Indicates it is a read or write operation. - @param[in, out] Token A pointer to the token associated with the transaction. - - @retval EFI_SUCCESS The data was read/written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be read/written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read/write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -SdReadWrite ( - IN SD_DEVICE *Device, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT VOID *Buffer, - IN UINTN BufferSize, - IN BOOLEAN IsRead, - IN OUT EFI_BLOCK_IO2_TOKEN *Token - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN BlockNum; - UINTN IoAlign; - UINTN Remaining; - UINT32 MaxBlock; - BOOLEAN LastRw; - - Status = EFI_SUCCESS; - Media = &Device->BlockMedia; - LastRw = FALSE; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (!IsRead && Media->ReadOnly) { - return EFI_WRITE_PROTECTED; - } - - // - // Check parameters. - // - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - gBS->SignalEvent (Token->Event); - } - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - BlockNum = BufferSize / BlockSize; - if ((Lba + BlockNum - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if (IoAlign > 0 && (((UINTN) Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - } - - // - // Start to execute data transfer. The max block number in single cmd is 65535 blocks. - // - Remaining = BlockNum; - MaxBlock = 0xFFFF; - - while (Remaining > 0) { - if (Remaining <= MaxBlock) { - BlockNum = Remaining; - LastRw = TRUE; - } else { - BlockNum = MaxBlock; - } - - BufferSize = BlockNum * BlockSize; - if (BlockNum == 1) { - Status = SdRwSingleBlock (Device, Lba, Buffer, BufferSize, IsRead, Token, LastRw); - } else { - Status = SdRwMultiBlocks (Device, Lba, Buffer, BufferSize, IsRead, Token, LastRw); - } - if (EFI_ERROR (Status)) { - return Status; - } - DEBUG ((EFI_D_INFO, "Sd%a(): Lba 0x%x BlkNo 0x%x Event %p with %r\n", IsRead ? "Read" : "Write", Lba, BlockNum, Token->Event, Status)); - - Lba += BlockNum; - Buffer = (UINT8*)Buffer + BufferSize; - Remaining -= BlockNum; - } - - return Status; -} - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -SdReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EFI_STATUS Status; - SD_DEVICE *Device; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - - Device = SD_DEVICE_DATA_FROM_BLKIO (This); - - PassThru = Device->Private->PassThru; - Status = PassThru->ResetDevice (PassThru, Device->Slot); - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - } - - return Status; -} - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -SdReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - SD_DEVICE *Device; - - Device = SD_DEVICE_DATA_FROM_BLKIO (This); - - Status = SdReadWrite (Device, MediaId, Lba, Buffer, BufferSize, TRUE, NULL); - return Status; -} - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -SdWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - SD_DEVICE *Device; - - Device = SD_DEVICE_DATA_FROM_BLKIO (This); - - Status = SdReadWrite (Device, MediaId, Lba, Buffer, BufferSize, FALSE, NULL); - return Status; -} - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -SdFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -{ - // - // return directly - // - return EFI_SUCCESS; -} - -/** - Reset the Block Device. - - @param[in] This Indicates a pointer to the calling context. - @param[in] ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -SdResetEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - SD_DEVICE *Device; - LIST_ENTRY *Link; - LIST_ENTRY *NextLink; - SD_REQUEST *Request; - EFI_TPL OldTpl; - - Device = SD_DEVICE_DATA_FROM_BLKIO2 (This); - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - for (Link = GetFirstNode (&Device->Queue); - !IsNull (&Device->Queue, Link); - Link = NextLink) { - NextLink = GetNextNode (&Device->Queue, Link); - RemoveEntryList (Link); - - Request = SD_REQUEST_FROM_LINK (Link); - - gBS->CloseEvent (Request->Event); - Request->Token->TransactionStatus = EFI_ABORTED; - - if (Request->IsEnd) { - gBS->SignalEvent (Request->Token->Event); - } - - FreePool (Request); - } - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; -} - -/** - Read BufferSize bytes from Lba into Buffer. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId Id of the media, changes every time the media is replaced. - @param[in] Lba The starting Logical Block Address to read from. - @param[in, out] Token A pointer to the token associated with the transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[out] Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The read request was queued if Event is not NULL. - The data was read correctly from the device if - the Event is NULL. - @retval EFI_DEVICE_ERROR The device reported an error while performing - the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack - of resources. - -**/ -EFI_STATUS -EFIAPI -SdReadBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - SD_DEVICE *Device; - - Device = SD_DEVICE_DATA_FROM_BLKIO2 (This); - - Status = SdReadWrite (Device, MediaId, Lba, Buffer, BufferSize, TRUE, Token); - return Status; -} - -/** - Write BufferSize bytes from Lba into Buffer. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] Lba The starting logical block address to be written. The - caller is responsible for writing to only legitimate - locations. - @param[in, out] Token A pointer to the token associated with the transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -SdWriteBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - SD_DEVICE *Device; - - Device = SD_DEVICE_DATA_FROM_BLKIO2 (This); - - Status = SdReadWrite (Device, MediaId, Lba, Buffer, BufferSize, FALSE, Token); - return Status; -} - -/** - Flush the Block Device. - - @param[in] This Indicates a pointer to the calling context. - @param[in, out] Token A pointer to the token associated with the transaction. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -SdFlushBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN OUT EFI_BLOCK_IO2_TOKEN *Token - ) -{ - // - // Signal event and return directly. - // - if (Token != NULL && Token->Event != NULL) { - Token->TransactionStatus = EFI_SUCCESS; - gBS->SignalEvent (Token->Event); - } - - return EFI_SUCCESS; -} - -/** - Set the erase start address through sync or async I/O request. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] StartLba The starting logical block address to be erased. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdEraseBlockStart ( - IN SD_DEVICE *Device, - IN EFI_LBA StartLba, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - SD_REQUEST *EraseBlockStart; - EFI_TPL OldTpl; - - EraseBlockStart = NULL; - PassThru = Device->Private->PassThru; - - EraseBlockStart = AllocateZeroPool (sizeof (SD_REQUEST)); - if (EraseBlockStart == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - EraseBlockStart->Signature = SD_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Device->Queue, &EraseBlockStart->Link); - gBS->RestoreTPL (OldTpl); - EraseBlockStart->Packet.SdMmcCmdBlk = &EraseBlockStart->SdMmcCmdBlk; - EraseBlockStart->Packet.SdMmcStatusBlk = &EraseBlockStart->SdMmcStatusBlk; - EraseBlockStart->Packet.Timeout = SD_GENERIC_TIMEOUT; - - EraseBlockStart->SdMmcCmdBlk.CommandIndex = SD_ERASE_WR_BLK_START; - EraseBlockStart->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - EraseBlockStart->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - - if (Device->SectorAddressing) { - EraseBlockStart->SdMmcCmdBlk.CommandArgument = (UINT32)StartLba; - } else { - EraseBlockStart->SdMmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (StartLba, Device->BlockMedia.BlockSize); - } - - EraseBlockStart->IsEnd = IsEnd; - EraseBlockStart->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - EraseBlockStart, - &EraseBlockStart->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - EraseBlockStart->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &EraseBlockStart->Packet, EraseBlockStart->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (EraseBlockStart != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlockStart->Link); - gBS->RestoreTPL (OldTpl); - if (EraseBlockStart->Event != NULL) { - gBS->CloseEvent (EraseBlockStart->Event); - } - FreePool (EraseBlockStart); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (EraseBlockStart != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlockStart->Link); - gBS->RestoreTPL (OldTpl); - FreePool (EraseBlockStart); - } - } - - return Status; -} - -/** - Set the erase end address through sync or async I/O request. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] EndLba The ending logical block address to be erased. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdEraseBlockEnd ( - IN SD_DEVICE *Device, - IN EFI_LBA EndLba, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - SD_REQUEST *EraseBlockEnd; - EFI_TPL OldTpl; - - EraseBlockEnd = NULL; - PassThru = Device->Private->PassThru; - - EraseBlockEnd = AllocateZeroPool (sizeof (SD_REQUEST)); - if (EraseBlockEnd == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - EraseBlockEnd->Signature = SD_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Device->Queue, &EraseBlockEnd->Link); - gBS->RestoreTPL (OldTpl); - EraseBlockEnd->Packet.SdMmcCmdBlk = &EraseBlockEnd->SdMmcCmdBlk; - EraseBlockEnd->Packet.SdMmcStatusBlk = &EraseBlockEnd->SdMmcStatusBlk; - EraseBlockEnd->Packet.Timeout = SD_GENERIC_TIMEOUT; - - EraseBlockEnd->SdMmcCmdBlk.CommandIndex = SD_ERASE_WR_BLK_END; - EraseBlockEnd->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - EraseBlockEnd->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; - - if (Device->SectorAddressing) { - EraseBlockEnd->SdMmcCmdBlk.CommandArgument = (UINT32)EndLba; - } else { - EraseBlockEnd->SdMmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (EndLba, Device->BlockMedia.BlockSize); - } - - EraseBlockEnd->IsEnd = IsEnd; - EraseBlockEnd->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - EraseBlockEnd, - &EraseBlockEnd->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - EraseBlockEnd->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &EraseBlockEnd->Packet, EraseBlockEnd->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (EraseBlockEnd != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlockEnd->Link); - gBS->RestoreTPL (OldTpl); - if (EraseBlockEnd->Event != NULL) { - gBS->CloseEvent (EraseBlockEnd->Event); - } - FreePool (EraseBlockEnd); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (EraseBlockEnd != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlockEnd->Link); - gBS->RestoreTPL (OldTpl); - FreePool (EraseBlockEnd); - } - } - - return Status; -} - -/** - Erase specified blocks through sync or async I/O request. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Token A pointer to the token associated with the transaction. - @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds. - This parameter is only meaningful in async I/O request. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdEraseBlock ( - IN SD_DEVICE *Device, - IN EFI_BLOCK_IO2_TOKEN *Token, - IN BOOLEAN IsEnd - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - SD_REQUEST *EraseBlock; - EFI_TPL OldTpl; - - EraseBlock = NULL; - PassThru = Device->Private->PassThru; - - EraseBlock = AllocateZeroPool (sizeof (SD_REQUEST)); - if (EraseBlock == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - EraseBlock->Signature = SD_REQUEST_SIGNATURE; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Device->Queue, &EraseBlock->Link); - gBS->RestoreTPL (OldTpl); - EraseBlock->Packet.SdMmcCmdBlk = &EraseBlock->SdMmcCmdBlk; - EraseBlock->Packet.SdMmcStatusBlk = &EraseBlock->SdMmcStatusBlk; - EraseBlock->Packet.Timeout = SD_GENERIC_TIMEOUT; - - EraseBlock->SdMmcCmdBlk.CommandIndex = SD_ERASE; - EraseBlock->SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; - EraseBlock->SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b; - - EraseBlock->IsEnd = IsEnd; - EraseBlock->Token = Token; - - if ((Token != NULL) && (Token->Event != NULL)) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - EraseBlock, - &EraseBlock->Event - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - EraseBlock->Event = NULL; - } - - Status = PassThru->PassThru (PassThru, Device->Slot, &EraseBlock->Packet, EraseBlock->Event); - -Error: - if ((Token != NULL) && (Token->Event != NULL)) { - // - // For asynchronous operation, only free request and event in error case. - // The request and event will be freed in asynchronous callback for success case. - // - if (EFI_ERROR (Status) && (EraseBlock != NULL)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlock->Link); - gBS->RestoreTPL (OldTpl); - if (EraseBlock->Event != NULL) { - gBS->CloseEvent (EraseBlock->Event); - } - FreePool (EraseBlock); - } - } else { - // - // For synchronous operation, free request whatever the execution result is. - // - if (EraseBlock != NULL) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - RemoveEntryList (&EraseBlock->Link); - gBS->RestoreTPL (OldTpl); - FreePool (EraseBlock); - } - } - - return Status; -} - -/** - Erase a specified number of device blocks. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the erase request is for. - @param[in] Lba The starting logical block address to be - erased. The caller is responsible for erasing - only legitimate locations. - @param[in, out] Token A pointer to the token associated with the - transaction. - @param[in] Size The size in bytes to be erased. This must be - a multiple of the physical block size of the - device. - - @retval EFI_SUCCESS The erase request was queued if Event is not - NULL. The data was erased correctly to the - device if the Event is NULL.to the device. - @retval EFI_WRITE_PROTECTED The device cannot be erased due to write - protection. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the erase operation. - @retval EFI_INVALID_PARAMETER The erase request contains LBAs that are not - valid. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - -**/ -EFI_STATUS -EFIAPI -SdEraseBlocks ( - IN EFI_ERASE_BLOCK_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_ERASE_BLOCK_TOKEN *Token, - IN UINTN Size - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN BlockNum; - EFI_LBA LastLba; - SD_DEVICE *Device; - - Status = EFI_SUCCESS; - Device = SD_DEVICE_DATA_FROM_ERASEBLK (This); - Media = &Device->BlockMedia; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Media->ReadOnly) { - return EFI_WRITE_PROTECTED; - } - - // - // Check parameters. - // - BlockSize = Media->BlockSize; - if ((Size % BlockSize) != 0) { - return EFI_INVALID_PARAMETER; - } - - BlockNum = Size / BlockSize; - if ((Lba + BlockNum - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - } - - LastLba = Lba + BlockNum - 1; - - Status = SdEraseBlockStart (Device, Lba, (EFI_BLOCK_IO2_TOKEN*)Token, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdEraseBlockEnd (Device, LastLba, (EFI_BLOCK_IO2_TOKEN*)Token, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdEraseBlock (Device, (EFI_BLOCK_IO2_TOKEN*)Token, TRUE); - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG ((EFI_D_ERROR, "SdEraseBlocks(): Lba 0x%x BlkNo 0x%x Event %p with %r\n", Lba, BlockNum, Token->Event, Status)); - - return Status; -} - diff --git a/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.h b/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.h deleted file mode 100644 index 227b45bebf..0000000000 --- a/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.h +++ /dev/null @@ -1,258 +0,0 @@ -/** @file - Header file for SdDxe Driver. - - This file defines common data structures, macro definitions and some module - internal function header files. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SD_BLOCK_IO_H_ -#define _SD_BLOCK_IO_H_ - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -SdReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -SdReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -SdWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -SdFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ); - -/** - Reset the Block Device. - - @param[in] This Indicates a pointer to the calling context. - @param[in] ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -SdResetEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId Id of the media, changes every time the media is replaced. - @param[in] Lba The starting Logical Block Address to read from. - @param[in, out] Token A pointer to the token associated with the transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[out] Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The read request was queued if Event is not NULL. - The data was read correctly from the device if - the Event is NULL. - @retval EFI_DEVICE_ERROR The device reported an error while performing - the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack - of resources. - -**/ -EFI_STATUS -EFIAPI -SdReadBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] Lba The starting logical block address to be written. The - caller is responsible for writing to only legitimate - locations. - @param[in, out] Token A pointer to the token associated with the transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device block size. - @param[in] Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -SdWriteBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - @param[in] This Indicates a pointer to the calling context. - @param[in, out] Token A pointer to the token associated with the transaction. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -SdFlushBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN OUT EFI_BLOCK_IO2_TOKEN *Token - ); - -/** - Erase a specified number of device blocks. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the erase request is for. - @param[in] Lba The starting logical block address to be - erased. The caller is responsible for erasing - only legitimate locations. - @param[in, out] Token A pointer to the token associated with the - transaction. - @param[in] Size The size in bytes to be erased. This must be - a multiple of the physical block size of the - device. - - @retval EFI_SUCCESS The erase request was queued if Event is not - NULL. The data was erased correctly to the - device if the Event is NULL.to the device. - @retval EFI_WRITE_PROTECTED The device cannot be erased due to write - protection. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the erase operation. - @retval EFI_INVALID_PARAMETER The erase request contains LBAs that are not - valid. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - -**/ -EFI_STATUS -EFIAPI -SdEraseBlocks ( - IN EFI_ERASE_BLOCK_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_ERASE_BLOCK_TOKEN *Token, - IN UINTN Size - ); - -#endif - diff --git a/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.c b/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.c deleted file mode 100644 index 0cf9067701..0000000000 --- a/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.c +++ /dev/null @@ -1,903 +0,0 @@ -/** @file - The SdDxe driver is used to manage the SD memory card device. - - It produces BlockIo and BlockIo2 protocols to allow upper layer - access the SD memory card device. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "SdDxe.h" - -// -// SdDxe Driver Binding Protocol Instance -// -EFI_DRIVER_BINDING_PROTOCOL gSdDxeDriverBinding = { - SdDxeDriverBindingSupported, - SdDxeDriverBindingStart, - SdDxeDriverBindingStop, - 0x10, - NULL, - NULL -}; - -// -// Template for SD_DEVICE data structure. -// -SD_DEVICE mSdDeviceTemplate = { - SD_DEVICE_SIGNATURE, // Signature - NULL, // Handle - NULL, // DevicePath - 0xFF, // Slot - FALSE, // SectorAddressing - { // BlockIo - EFI_BLOCK_IO_PROTOCOL_REVISION, - NULL, - SdReset, - SdReadBlocks, - SdWriteBlocks, - SdFlushBlocks - }, - { // BlockIo2 - NULL, - SdResetEx, - SdReadBlocksEx, - SdWriteBlocksEx, - SdFlushBlocksEx - }, - { // BlockMedia - 0, // MediaId - FALSE, // RemovableMedia - TRUE, // MediaPresent - FALSE, // LogicPartition - FALSE, // ReadOnly - FALSE, // WritingCache - 0x200, // BlockSize - 0, // IoAlign - 0 // LastBlock - }, - { // EraseBlock - EFI_ERASE_BLOCK_PROTOCOL_REVISION, - 1, - SdEraseBlocks - }, - { // Queue - NULL, - NULL - }, - { // Csd - 0, - }, - { // Cid - 0, - }, - NULL, // ControllerNameTable - { // ModelName - 0, - }, - NULL // Private -}; - -/** - Decode and print SD CSD Register content. - - @param[in] Csd Pointer to SD_CSD data structure. - - @retval EFI_SUCCESS The function completed successfully -**/ -EFI_STATUS -DumpCsd ( - IN SD_CSD *Csd - ) -{ - SD_CSD2 *Csd2; - - DEBUG((DEBUG_INFO, "== Dump Sd Csd Register==\n")); - DEBUG((DEBUG_INFO, " CSD structure 0x%x\n", Csd->CsdStructure)); - DEBUG((DEBUG_INFO, " Data read access-time 1 0x%x\n", Csd->Taac)); - DEBUG((DEBUG_INFO, " Data read access-time 2 0x%x\n", Csd->Nsac)); - DEBUG((DEBUG_INFO, " Max. bus clock frequency 0x%x\n", Csd->TranSpeed)); - DEBUG((DEBUG_INFO, " Device command classes 0x%x\n", Csd->Ccc)); - DEBUG((DEBUG_INFO, " Max. read data block length 0x%x\n", Csd->ReadBlLen)); - DEBUG((DEBUG_INFO, " Partial blocks for read allowed 0x%x\n", Csd->ReadBlPartial)); - DEBUG((DEBUG_INFO, " Write block misalignment 0x%x\n", Csd->WriteBlkMisalign)); - DEBUG((DEBUG_INFO, " Read block misalignment 0x%x\n", Csd->ReadBlkMisalign)); - DEBUG((DEBUG_INFO, " DSR implemented 0x%x\n", Csd->DsrImp)); - if (Csd->CsdStructure == 0) { - DEBUG((DEBUG_INFO, " Device size 0x%x\n", Csd->CSizeLow | (Csd->CSizeHigh << 2))); - DEBUG((DEBUG_INFO, " Max. read current @ VDD min 0x%x\n", Csd->VddRCurrMin)); - DEBUG((DEBUG_INFO, " Max. read current @ VDD max 0x%x\n", Csd->VddRCurrMax)); - DEBUG((DEBUG_INFO, " Max. write current @ VDD min 0x%x\n", Csd->VddWCurrMin)); - DEBUG((DEBUG_INFO, " Max. write current @ VDD max 0x%x\n", Csd->VddWCurrMax)); - } else { - Csd2 = (SD_CSD2*)(VOID*)Csd; - DEBUG((DEBUG_INFO, " Device size 0x%x\n", Csd2->CSizeLow | (Csd->CSizeHigh << 16))); - } - DEBUG((DEBUG_INFO, " Erase sector size 0x%x\n", Csd->SectorSize)); - DEBUG((DEBUG_INFO, " Erase single block enable 0x%x\n", Csd->EraseBlkEn)); - DEBUG((DEBUG_INFO, " Write protect group size 0x%x\n", Csd->WpGrpSize)); - DEBUG((DEBUG_INFO, " Write protect group enable 0x%x\n", Csd->WpGrpEnable)); - DEBUG((DEBUG_INFO, " Write speed factor 0x%x\n", Csd->R2WFactor)); - DEBUG((DEBUG_INFO, " Max. write data block length 0x%x\n", Csd->WriteBlLen)); - DEBUG((DEBUG_INFO, " Partial blocks for write allowed 0x%x\n", Csd->WriteBlPartial)); - DEBUG((DEBUG_INFO, " File format group 0x%x\n", Csd->FileFormatGrp)); - DEBUG((DEBUG_INFO, " Copy flag (OTP) 0x%x\n", Csd->Copy)); - DEBUG((DEBUG_INFO, " Permanent write protection 0x%x\n", Csd->PermWriteProtect)); - DEBUG((DEBUG_INFO, " Temporary write protection 0x%x\n", Csd->TmpWriteProtect)); - DEBUG((DEBUG_INFO, " File format 0x%x\n", Csd->FileFormat)); - - return EFI_SUCCESS; -} - -/** - Get SD device model name. - - @param[in, out] Device The pointer to the SD_DEVICE data structure. - @param[in] Cid Pointer to SD_CID data structure. - - @retval EFI_SUCCESS The function completed successfully - -**/ -EFI_STATUS -GetSdModelName ( - IN OUT SD_DEVICE *Device, - IN SD_CID *Cid - ) -{ - CHAR8 String[SD_MODEL_NAME_MAX_LEN]; - - ZeroMem (String, sizeof (String)); - CopyMem (String, Cid->OemId, sizeof (Cid->OemId)); - String[sizeof (Cid->OemId)] = ' '; - CopyMem (String + sizeof (Cid->OemId) + 1, Cid->ProductName, sizeof (Cid->ProductName)); - String[sizeof (Cid->OemId) + sizeof (Cid->ProductName)] = ' '; - CopyMem (String + sizeof (Cid->OemId) + sizeof (Cid->ProductName) + 1, Cid->ProductSerialNumber, sizeof (Cid->ProductSerialNumber)); - - AsciiStrToUnicodeStrS (String, Device->ModelName, sizeof (Device->ModelName) / sizeof (Device->ModelName[0])); - - return EFI_SUCCESS; -} - -/** - Discover user area partition in the SD device. - - @param[in] Device The pointer to the SD_DEVICE data structure. - - @retval EFI_SUCCESS The user area partition in the SD device is successfully identified. - @return Others Some error occurs when identifying the user area. - -**/ -EFI_STATUS -DiscoverUserArea ( - IN SD_DEVICE *Device - ) -{ - EFI_STATUS Status; - SD_CSD *Csd; - SD_CSD2 *Csd2; - SD_CID *Cid; - UINT64 Capacity; - UINT32 DevStatus; - UINT16 Rca; - UINT32 CSize; - UINT32 CSizeMul; - UINT32 ReadBlLen; - - // - // Deselect the device to force it enter stby mode. - // Note here we don't judge return status as some SD devices return - // error but the state has been stby. - // - SdSelect (Device, 0); - - Status = SdSetRca (Device, &Rca); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "DiscoverUserArea(): Assign new Rca = 0x%x fails with %r\n", Rca, Status)); - return Status; - } - - Csd = &Device->Csd; - Status = SdGetCsd (Device, Rca, Csd); - if (EFI_ERROR (Status)) { - return Status; - } - DumpCsd (Csd); - - Cid = &Device->Cid; - Status = SdGetCid (Device, Rca, Cid); - if (EFI_ERROR (Status)) { - return Status; - } - GetSdModelName (Device, Cid); - - Status = SdSelect (Device, Rca); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "DiscoverUserArea(): Reselect the device 0x%x fails with %r\n", Rca, Status)); - return Status; - } - - Status = SdSendStatus (Device, Rca, &DevStatus); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Csd->CsdStructure == 0) { - Device->SectorAddressing = FALSE; - CSize = (Csd->CSizeHigh << 2 | Csd->CSizeLow) + 1; - CSizeMul = (1 << (Csd->CSizeMul + 2)); - ReadBlLen = (1 << (Csd->ReadBlLen)); - Capacity = MultU64x32 (MultU64x32 ((UINT64)CSize, CSizeMul), ReadBlLen); - } else { - Device->SectorAddressing = TRUE; - Csd2 = (SD_CSD2*)(VOID*)Csd; - CSize = (Csd2->CSizeHigh << 16 | Csd2->CSizeLow) + 1; - Capacity = MultU64x32 ((UINT64)CSize, SIZE_512KB); - } - - Device->BlockIo.Media = &Device->BlockMedia; - Device->BlockIo2.Media = &Device->BlockMedia; - Device->BlockMedia.IoAlign = Device->Private->PassThru->IoAlign; - Device->BlockMedia.BlockSize = 0x200; - Device->BlockMedia.LastBlock = 0x00; - Device->BlockMedia.RemovableMedia = TRUE; - Device->BlockMedia.MediaPresent = TRUE; - Device->BlockMedia.LogicalPartition = FALSE; - Device->BlockMedia.LastBlock = DivU64x32 (Capacity, Device->BlockMedia.BlockSize) - 1; - - if (Csd->EraseBlkEn) { - Device->EraseBlock.EraseLengthGranularity = 1; - } else { - Device->EraseBlock.EraseLengthGranularity = (Csd->SectorSize + 1) * (1 << (Csd->WriteBlLen - 9)); - } - - return Status; -} - -/** - Scan SD Bus to discover the device. - - @param[in] Private The SD driver private data structure. - @param[in] Slot The slot number to check device present. - - @retval EFI_SUCCESS Successfully to discover the device and attach - SdMmcIoProtocol to it. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack - of resources. - @retval EFI_ALREADY_STARTED The device was discovered before. - @retval Others Fail to discover the device. - -**/ -EFI_STATUS -EFIAPI -DiscoverSdDevice ( - IN SD_DRIVER_PRIVATE_DATA *Private, - IN UINT8 Slot - ) -{ - EFI_STATUS Status; - SD_DEVICE *Device; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - EFI_HANDLE DeviceHandle; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - - Device = NULL; - DevicePath = NULL; - NewDevicePath = NULL; - RemainingDevicePath = NULL; - PassThru = Private->PassThru; - - // - // Build Device Path - // - Status = PassThru->BuildDevicePath ( - PassThru, - Slot, - &DevicePath - ); - if (EFI_ERROR(Status)) { - return Status; - } - - if (DevicePath->SubType != MSG_SD_DP) { - Status = EFI_UNSUPPORTED; - goto Error; - } - - NewDevicePath = AppendDevicePathNode ( - Private->ParentDevicePath, - DevicePath - ); - - if (NewDevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - DeviceHandle = NULL; - RemainingDevicePath = NewDevicePath; - Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle); - if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) { - // - // The device has been started, directly return to fast boot. - // - Status = EFI_ALREADY_STARTED; - goto Error; - } - - // - // Allocate buffer to store SD_DEVICE private data. - // - Device = AllocateCopyPool (sizeof (SD_DEVICE), &mSdDeviceTemplate); - if (Device == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - Device->DevicePath = NewDevicePath; - Device->Slot = Slot; - Device->Private = Private; - InitializeListHead (&Device->Queue); - - // - // Expose user area in the Sd memory card to upper layer. - // - Status = DiscoverUserArea (Device); - if (EFI_ERROR(Status)) { - goto Error; - } - - Device->ControllerNameTable = NULL; - AddUnicodeString2 ( - "eng", - gSdDxeComponentName.SupportedLanguages, - &Device->ControllerNameTable, - Device->ModelName, - TRUE - ); - AddUnicodeString2 ( - "en", - gSdDxeComponentName.SupportedLanguages, - &Device->ControllerNameTable, - Device->ModelName, - FALSE - ); - - Status = gBS->InstallMultipleProtocolInterfaces ( - &Device->Handle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - &gEfiBlockIo2ProtocolGuid, - &Device->BlockIo2, - &gEfiEraseBlockProtocolGuid, - &Device->EraseBlock, - NULL - ); - - if (!EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Private->Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID **) &(Private->PassThru), - Private->DriverBindingHandle, - Device->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - } - -Error: - FreePool (DevicePath); - - if (EFI_ERROR (Status) && (NewDevicePath != NULL)) { - FreePool (NewDevicePath); - } - - if (EFI_ERROR (Status) && (Device != NULL)) { - FreePool (Device); - } - - return Status; -} - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -SdDxeDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - UINT8 Slot; - - // - // Test EFI_SD_MMC_PASS_THRU_PROTOCOL on the controller handle. - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID**) &PassThru, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Test RemainingDevicePath is valid or not. - // - if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) { - Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot); - if (EFI_ERROR (Status)) { - // - // Close the I/O Abstraction(s) used to perform the supported test - // - gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - Controller - ); - return Status; - } - } - - // - // Close the I/O Abstraction(s) used to perform the supported test - // - gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - // - // Open the EFI Device Path protocol needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - return Status; -} - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -SdDxeDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - SD_DRIVER_PRIVATE_DATA *Private; - UINT8 Slot; - - Private = NULL; - PassThru = NULL; - Status = gBS->OpenProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID **) &PassThru, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) { - return Status; - } - - // - // Check EFI_ALREADY_STARTED to reuse the original SD_DRIVER_PRIVATE_DATA. - // - if (Status != EFI_ALREADY_STARTED) { - Private = AllocateZeroPool (sizeof (SD_DRIVER_PRIVATE_DATA)); - if (Private == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - Private->PassThru = PassThru; - Private->Controller = Controller; - Private->ParentDevicePath = ParentDevicePath; - Private->DriverBindingHandle = This->DriverBindingHandle; - - Status = gBS->InstallProtocolInterface ( - &Controller, - &gEfiCallerIdGuid, - EFI_NATIVE_INTERFACE, - Private - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } else { - Status = gBS->OpenProtocol ( - Controller, - &gEfiCallerIdGuid, - (VOID **) &Private, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } - - if (RemainingDevicePath == NULL) { - Slot = 0xFF; - while (TRUE) { - Status = PassThru->GetNextSlot (PassThru, &Slot); - if (EFI_ERROR (Status)) { - // - // Cannot find more legal slots. - // - Status = EFI_SUCCESS; - break; - } - - Status = DiscoverSdDevice (Private, Slot); - if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { - break; - } - } - } else if (!IsDevicePathEnd (RemainingDevicePath)) { - Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot); - if (!EFI_ERROR (Status)) { - Status = DiscoverSdDevice (Private, Slot); - } - } - -Error: - if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { - gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - if (Private != NULL) { - gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiCallerIdGuid, - Private, - NULL - ); - FreePool (Private); - } - } - return Status; -} - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -SdDxeDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_STATUS Status; - BOOLEAN AllChildrenStopped; - UINTN Index; - SD_DRIVER_PRIVATE_DATA *Private; - SD_DEVICE *Device; - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_BLOCK_IO2_PROTOCOL *BlockIo2; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - LIST_ENTRY *Link; - LIST_ENTRY *NextLink; - SD_REQUEST *Request; - EFI_TPL OldTpl; - - if (NumberOfChildren == 0) { - Status = gBS->OpenProtocol ( - Controller, - &gEfiCallerIdGuid, - (VOID **) &Private, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - gBS->UninstallProtocolInterface ( - Controller, - &gEfiCallerIdGuid, - Private - ); - gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - FreePool (Private); - - return EFI_SUCCESS; - } - - AllChildrenStopped = TRUE; - - for (Index = 0; Index < NumberOfChildren; Index++) { - BlockIo = NULL; - BlockIo2 = NULL; - Status = gBS->OpenProtocol ( - ChildHandleBuffer[Index], - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - Status = gBS->OpenProtocol ( - ChildHandleBuffer[Index], - &gEfiBlockIo2ProtocolGuid, - (VOID **) &BlockIo2, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - continue; - } - } - - if (BlockIo != NULL) { - Device = SD_DEVICE_DATA_FROM_BLKIO (BlockIo); - } else { - ASSERT (BlockIo2 != NULL); - Device = SD_DEVICE_DATA_FROM_BLKIO2 (BlockIo2); - } - - // - // Free all on-going async tasks. - // - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - for (Link = GetFirstNode (&Device->Queue); - !IsNull (&Device->Queue, Link); - Link = NextLink) { - NextLink = GetNextNode (&Device->Queue, Link); - RemoveEntryList (Link); - - Request = SD_REQUEST_FROM_LINK (Link); - - gBS->CloseEvent (Request->Event); - Request->Token->TransactionStatus = EFI_ABORTED; - - if (Request->IsEnd) { - gBS->SignalEvent (Request->Token->Event); - } - - FreePool (Request); - } - gBS->RestoreTPL (OldTpl); - - // - // Close the child handle - // - Status = gBS->CloseProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - This->DriverBindingHandle, - ChildHandleBuffer[Index] - ); - - Status = gBS->UninstallMultipleProtocolInterfaces ( - ChildHandleBuffer[Index], - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - &gEfiBlockIo2ProtocolGuid, - &Device->BlockIo2, - &gEfiEraseBlockProtocolGuid, - &Device->EraseBlock, - NULL - ); - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - gBS->OpenProtocol ( - Controller, - &gEfiSdMmcPassThruProtocolGuid, - (VOID **)&PassThru, - This->DriverBindingHandle, - ChildHandleBuffer[Index], - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - } else { - FreePool (Device->DevicePath); - FreeUnicodeStringTable (Device->ControllerNameTable); - FreePool (Device); - } - } - - if (!AllChildrenStopped) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - The user Entry Point for module SdDxe. The user code starts with this function. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval other Some errors occur when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -InitializeSdDxe ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - // - // Install driver model protocol(s). - // - Status = EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gSdDxeDriverBinding, - ImageHandle, - &gSdDxeComponentName, - &gSdDxeComponentName2 - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} - diff --git a/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.h b/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.h deleted file mode 100644 index 0ba72b7f9c..0000000000 --- a/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.h +++ /dev/null @@ -1,474 +0,0 @@ -/** @file - Header file for SdDxe Driver. - - This file defines common data structures, macro definitions and some module - internal function header files. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SD_DXE_H_ -#define _SD_DXE_H_ - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "SdBlockIo.h" -// -// Global Variables -// -extern EFI_DRIVER_BINDING_PROTOCOL gSdDxeDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gSdDxeComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gSdDxeComponentName2; - -#define SD_DEVICE_SIGNATURE SIGNATURE_32 ('S', 'D', 't', 'f') - -#define SD_DEVICE_DATA_FROM_BLKIO(a) \ - CR(a, SD_DEVICE, BlockIo, SD_DEVICE_SIGNATURE) - -#define SD_DEVICE_DATA_FROM_BLKIO2(a) \ - CR(a, SD_DEVICE, BlockIo2, SD_DEVICE_SIGNATURE) - -#define SD_DEVICE_DATA_FROM_ERASEBLK(a) \ - CR(a, SD_DEVICE, EraseBlock, SD_DEVICE_SIGNATURE) - -// -// Take 2.5 seconds as generic time out value, 1 microsecond as unit. -// -#define SD_GENERIC_TIMEOUT 2500 * 1000 - -#define SD_REQUEST_SIGNATURE SIGNATURE_32 ('S', 'D', 'R', 'E') - -#define SD_MODEL_NAME_MAX_LEN 32 - -typedef struct _SD_DEVICE SD_DEVICE; -typedef struct _SD_DRIVER_PRIVATE_DATA SD_DRIVER_PRIVATE_DATA; - -// -// Asynchronous I/O request. -// -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; - EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; - EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; - - BOOLEAN IsEnd; - - EFI_BLOCK_IO2_TOKEN *Token; - - EFI_EVENT Event; -} SD_REQUEST; - -#define SD_REQUEST_FROM_LINK(a) \ - CR(a, SD_REQUEST, Link, SD_REQUEST_SIGNATURE) - -struct _SD_DEVICE { - UINT32 Signature; - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UINT8 Slot; - BOOLEAN SectorAddressing; - EFI_BLOCK_IO_PROTOCOL BlockIo; - EFI_BLOCK_IO2_PROTOCOL BlockIo2; - EFI_BLOCK_IO_MEDIA BlockMedia; - EFI_ERASE_BLOCK_PROTOCOL EraseBlock; - - LIST_ENTRY Queue; - - SD_CSD Csd; - SD_CID Cid; - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - // - // The model name consists of three fields in CID register - // 1) OEM/Application ID (2 bytes) - // 2) Product Name (5 bytes) - // 3) Product Serial Number (4 bytes) - // The delimiters of these fields are whitespace. - // - CHAR16 ModelName[SD_MODEL_NAME_MAX_LEN]; - SD_DRIVER_PRIVATE_DATA *Private; -} ; - -// -// SD DXE driver private data structure -// -struct _SD_DRIVER_PRIVATE_DATA { - EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru; - EFI_HANDLE Controller; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_HANDLE DriverBindingHandle; -} ; - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -SdDxeDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -SdDxeDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -SdDxeDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -SdDxeComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -SdDxeComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -/** - Send command SET_RELATIVE_ADDRESS to the device to set the device address. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[out] Rca The relative device address to assign. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdSetRca ( - IN SD_DEVICE *Device, - OUT UINT16 *Rca - ); - -/** - Send command SELECT to the device to select/deselect the device. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Rca The relative device address to use. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdSelect ( - IN SD_DEVICE *Device, - IN UINT16 Rca - ); - -/** - Send command SEND_STATUS to the device to get device status. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] DevStatus The buffer to store the device status. - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdSendStatus ( - IN SD_DEVICE *Device, - IN UINT16 Rca, - OUT UINT32 *DevStatus - ); - -/** - Send command SEND_CSD to the device to get the CSD register data. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] Csd The buffer to store the SD_CSD register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdGetCsd ( - IN SD_DEVICE *Device, - IN UINT16 Rca, - OUT SD_CSD *Csd - ); - -/** - Send command SEND_CID to the device to get the CID register data. - - @param[in] Device A pointer to the SD_DEVICE instance. - @param[in] Rca The relative device address to use. - @param[out] Cid The buffer to store the SD_CID register data. - - @retval EFI_SUCCESS The request is executed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources. - @retval Others The request could not be executed successfully. - -**/ -EFI_STATUS -SdGetCid ( - IN SD_DEVICE *Device, - IN UINT16 Rca, - OUT SD_CID *Cid - ); - -#endif - diff --git a/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf b/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf deleted file mode 100644 index 6f5e6ca72e..0000000000 --- a/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf +++ /dev/null @@ -1,66 +0,0 @@ -## @file -# SdDxe driver is used to manage the SD memory card device. -# -# It produces BlockIo and BlockIo2 protocols to allow upper layer -# access the SD memory card device. -# -# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = SdDxe - MODULE_UNI_FILE = SdDxe.uni - FILE_GUID = 430AC2F7-EEC6-4093-94F7-9F825A7C1C40 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = InitializeSdDxe - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# -# DRIVER_BINDING = gSdDxeDriverBinding -# COMPONENT_NAME = gSdDxeComponentName -# COMPONENT_NAME2 = gSdDxeComponentName2 -# - -[Sources.common] - ComponentName.c - SdDxe.c - SdDxe.h - SdBlockIo.c - SdBlockIo.h - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - DevicePathLib - UefiBootServicesTableLib - MemoryAllocationLib - BaseMemoryLib - UefiLib - BaseLib - UefiDriverEntryPoint - DebugLib - -[Protocols] - gEfiSdMmcPassThruProtocolGuid ## TO_START - gEfiBlockIoProtocolGuid ## BY_START - gEfiBlockIo2ProtocolGuid ## BY_START - gEfiEraseBlockProtocolGuid ## BY_START - ## TO_START - ## BY_START - gEfiDevicePathProtocolGuid - diff --git a/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.uni b/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.uni deleted file mode 100644 index dc77ab86f0..0000000000 --- a/MdeModulePkg/Bus/Sd/SdDxe/SdDxe.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// SD memory card device driver to manage the SD memory card device and provide interface for upper layer -// access. -// -// Copyright (c) 2015, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "SD device driver to manage the SD memory card device and provide interface for upper layer access" - -#string STR_MODULE_DESCRIPTION #language en-US "This driver follows the UEFI driver model and layers on the SdMmcPassThru protocol. It installs BlockIo and BlockIo2 protocols on the SD device." - diff --git a/MdeModulePkg/Bus/Sd/SdDxe/SdDxeExtra.uni b/MdeModulePkg/Bus/Sd/SdDxe/SdDxeExtra.uni deleted file mode 100644 index dc77ab86f0..0000000000 --- a/MdeModulePkg/Bus/Sd/SdDxe/SdDxeExtra.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// SD memory card device driver to manage the SD memory card device and provide interface for upper layer -// access. -// -// Copyright (c) 2015, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "SD device driver to manage the SD memory card device and provide interface for upper layer access" - -#string STR_MODULE_DESCRIPTION #language en-US "This driver follows the UEFI driver model and layers on the SdMmcPassThru protocol. It installs BlockIo and BlockIo2 protocols on the SD device." - -- cgit v1.2.3