UfsBlockIoPeimGetMediaInfo,\r
UfsBlockIoPeimReadBlocks\r
},\r
+ { // BlkIo2Ppi\r
+ EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION,\r
+ UfsBlockIoPeimGetDeviceNo2,\r
+ UfsBlockIoPeimGetMediaInfo2,\r
+ UfsBlockIoPeimReadBlocks2\r
+ },\r
{ // BlkIoPpiList\r
- EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+ EFI_PEI_PPI_DESCRIPTOR_PPI,\r
&gEfiPeiVirtualBlockIoPpiGuid,\r
NULL\r
},\r
+ { // BlkIo2PpiList\r
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+ &gEfiPeiVirtualBlockIo2PpiGuid,\r
+ NULL\r
+ },\r
{ // Media\r
{\r
- UfsDevice,\r
+ MSG_UFS_DP,\r
+ FALSE,\r
TRUE,\r
- 0,\r
- 0x1000\r
+ FALSE,\r
+ 0x1000,\r
+ 0\r
},\r
{\r
- UfsDevice,\r
+ MSG_UFS_DP,\r
+ FALSE,\r
TRUE,\r
- 0,\r
- 0x1000\r
+ FALSE,\r
+ 0x1000,\r
+ 0\r
},\r
{\r
- UfsDevice,\r
+ MSG_UFS_DP,\r
+ FALSE,\r
TRUE,\r
- 0,\r
- 0x1000\r
+ FALSE,\r
+ 0x1000,\r
+ 0\r
},\r
{\r
- UfsDevice,\r
+ MSG_UFS_DP,\r
+ FALSE,\r
TRUE,\r
- 0,\r
- 0x1000\r
+ FALSE,\r
+ 0x1000,\r
+ 0\r
},\r
{\r
- UfsDevice,\r
+ MSG_UFS_DP,\r
+ FALSE,\r
TRUE,\r
- 0,\r
- 0x1000\r
+ FALSE,\r
+ 0x1000,\r
+ 0\r
},\r
{\r
- UfsDevice,\r
+ MSG_UFS_DP,\r
+ FALSE,\r
TRUE,\r
- 0,\r
- 0x1000\r
+ FALSE,\r
+ 0x1000,\r
+ 0\r
},\r
{\r
- UfsDevice,\r
+ MSG_UFS_DP,\r
+ FALSE,\r
TRUE,\r
- 0,\r
- 0x1000\r
+ FALSE,\r
+ 0x1000,\r
+ 0\r
},\r
{\r
- UfsDevice,\r
+ MSG_UFS_DP,\r
+ FALSE,\r
TRUE,\r
- 0,\r
- 0x1000\r
+ FALSE,\r
+ 0x1000,\r
+ 0\r
}\r
},\r
0, // UfsHcBase\r
**/\r
EFI_STATUS\r
UfsPeimParsingSenseKeys (\r
- IN EFI_PEI_BLOCK_IO_MEDIA *Media,\r
+ IN EFI_PEI_BLOCK_IO2_MEDIA *Media,\r
IN EFI_SCSI_SENSE_DATA *SenseData,\r
OUT BOOLEAN *NeedRetry\r
)\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
- MediaInfo->LastBlock = (Capacity16.LastLba3 << 24) | (Capacity16.LastLba2 << 16) | (Capacity16.LastLba1 << 8) | Capacity16.LastLba0;\r
- MediaInfo->LastBlock |= ((UINT64)Capacity16.LastLba7 << 56) | ((UINT64)Capacity16.LastLba6 << 48) | ((UINT64)Capacity16.LastLba5 << 40) | ((UINT64)Capacity16.LastLba4 << 32);\r
- MediaInfo->BlockSize = (Capacity16.BlockSize3 << 24) | (Capacity16.BlockSize2 << 16) | (Capacity16.BlockSize1 << 8) | Capacity16.BlockSize0;\r
+ Private->Media[DeviceIndex].LastBlock = (Capacity16.LastLba3 << 24) | (Capacity16.LastLba2 << 16) | (Capacity16.LastLba1 << 8) | Capacity16.LastLba0;\r
+ Private->Media[DeviceIndex].LastBlock |= ((UINT64)Capacity16.LastLba7 << 56) | ((UINT64)Capacity16.LastLba6 << 48) | ((UINT64)Capacity16.LastLba5 << 40) | ((UINT64)Capacity16.LastLba4 << 32);\r
+ Private->Media[DeviceIndex].BlockSize = (Capacity16.BlockSize3 << 24) | (Capacity16.BlockSize2 << 16) | (Capacity16.BlockSize1 << 8) | Capacity16.BlockSize0;\r
} else {\r
- MediaInfo->LastBlock = (Capacity.LastLba3 << 24) | (Capacity.LastLba2 << 16) | (Capacity.LastLba1 << 8) | Capacity.LastLba0;\r
- MediaInfo->BlockSize = (Capacity.BlockSize3 << 24) | (Capacity.BlockSize2 << 16) | (Capacity.BlockSize1 << 8) | Capacity.BlockSize0;\r
+ Private->Media[DeviceIndex].LastBlock = (Capacity.LastLba3 << 24) | (Capacity.LastLba2 << 16) | (Capacity.LastLba1 << 8) | Capacity.LastLba0;\r
+ Private->Media[DeviceIndex].BlockSize = (Capacity.BlockSize3 << 24) | (Capacity.BlockSize2 << 16) | (Capacity.BlockSize1 << 8) | Capacity.BlockSize0;\r
}\r
\r
MediaInfo->DeviceType = UfsDevice;\r
- MediaInfo->MediaPresent = TRUE;\r
+ MediaInfo->MediaPresent = Private->Media[DeviceIndex].MediaPresent;\r
+ MediaInfo->LastBlock = (UINTN)Private->Media[DeviceIndex].LastBlock;\r
+ MediaInfo->BlockSize = Private->Media[DeviceIndex].BlockSize;\r
\r
return EFI_SUCCESS;\r
}\r
} while (NeedRetry);\r
\r
SenseDataLength = 0;\r
- if (Private->Media[DeviceIndex].LastBlock != ~((UINTN)0)) {\r
+ if (Private->Media[DeviceIndex].LastBlock < 0xfffffffful) {\r
Status = UfsPeimRead10 (\r
Private,\r
DeviceIndex,\r
return Status;\r
}\r
\r
+/**\r
+ Gets the count of block I/O devices that one specific block driver detects.\r
+\r
+ This function is used for getting the count of block I/O devices that one \r
+ specific block driver detects. To the PEI ATAPI driver, it returns the number\r
+ of all the detected ATAPI devices it detects during the enumeration process. \r
+ To the PEI legacy floppy driver, it returns the number of all the legacy \r
+ devices it finds during its enumeration process. If no device is detected, \r
+ then the function will return zero. \r
+ \r
+ @param[in] PeiServices General-purpose services that are available \r
+ to every PEIM.\r
+ @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI \r
+ instance.\r
+ @param[out] NumberBlockDevices The number of block I/O devices discovered.\r
+\r
+ @retval EFI_SUCCESS The operation performed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsBlockIoPeimGetDeviceNo2 (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,\r
+ OUT UINTN *NumberBlockDevices\r
+ )\r
+{\r
+ //\r
+ // For Ufs device, it has up to 8 normal Luns plus some well-known Luns.\r
+ // At PEI phase, we will only expose normal Luns to user.\r
+ // For those disabled Lun, when user try to access it, the operation would fail.\r
+ //\r
+ *NumberBlockDevices = UFS_PEIM_MAX_LUNS;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Gets a block device's media information.\r
+\r
+ This function will provide the caller with the specified block device's media \r
+ information. If the media changes, calling this function will update the media \r
+ information accordingly.\r
+\r
+ @param[in] PeiServices General-purpose services that are available to every\r
+ PEIM\r
+ @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.\r
+ @param[in] DeviceIndex Specifies the block device to which the function wants \r
+ to talk. Because the driver that implements Block I/O \r
+ PPIs will manage multiple block devices, the PPIs that \r
+ want to talk to a single device must specify the \r
+ device index that was assigned during the enumeration\r
+ process. This index is a number from one to \r
+ NumberBlockDevices.\r
+ @param[out] MediaInfo The media information of the specified block media. \r
+ The caller is responsible for the ownership of this \r
+ data structure.\r
+\r
+ @par Note: \r
+ The MediaInfo structure describes an enumeration of possible block device \r
+ types. This enumeration exists because no device paths are actually passed \r
+ across interfaces that describe the type or class of hardware that is publishing \r
+ the block I/O interface. This enumeration will allow for policy decisions\r
+ in the Recovery PEIM, such as "Try to recover from legacy floppy first, \r
+ LS-120 second, CD-ROM third." If there are multiple partitions abstracted \r
+ by a given device type, they should be reported in ascending order; this \r
+ order also applies to nested partitions, such as legacy MBR, where the \r
+ outermost partitions would have precedence in the reporting order. The \r
+ same logic applies to systems such as IDE that have precedence relationships \r
+ like "Master/Slave" or "Primary/Secondary". The master device should be \r
+ reported first, the slave second.\r
+ \r
+ @retval EFI_SUCCESS Media information about the specified block device \r
+ was obtained successfully.\r
+ @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware \r
+ error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsBlockIoPeimGetMediaInfo2 (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,\r
+ IN UINTN DeviceIndex,\r
+ OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UFS_PEIM_HC_PRIVATE_DATA *Private;\r
+ EFI_PEI_BLOCK_IO_MEDIA Media;\r
+\r
+ Private = GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This);\r
+ \r
+ Status = UfsBlockIoPeimGetMediaInfo (\r
+ PeiServices,\r
+ &Private->BlkIoPpi,\r
+ DeviceIndex,\r
+ &Media\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CopyMem (MediaInfo, &(Private->Media[DeviceIndex]), sizeof (EFI_PEI_BLOCK_IO2_MEDIA));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Reads the requested number of blocks from the specified block device.\r
+\r
+ The function reads the requested number of blocks from the device. All the \r
+ blocks are read, or an error is returned. If there is no media in the device,\r
+ the function returns EFI_NO_MEDIA.\r
+\r
+ @param[in] PeiServices General-purpose services that are available to \r
+ every PEIM.\r
+ @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.\r
+ @param[in] DeviceIndex Specifies the block device to which the function wants \r
+ to talk. Because the driver that implements Block I/O \r
+ PPIs will manage multiple block devices, PPIs that \r
+ want to talk to a single device must specify the device \r
+ index that was assigned during the enumeration process. \r
+ This index is a number from one to NumberBlockDevices.\r
+ @param[in] StartLBA The starting logical block address (LBA) to read from\r
+ on the device\r
+ @param[in] BufferSize The size of the Buffer in bytes. This number must be\r
+ a multiple of the intrinsic block size of the device.\r
+ @param[out] Buffer A pointer to the destination buffer for the data.\r
+ The caller is responsible for the ownership of the \r
+ buffer.\r
+ \r
+ @retval EFI_SUCCESS The data was read correctly from the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting \r
+ to perform the read operation.\r
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not \r
+ valid, or the buffer is not properly aligned.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of\r
+ the intrinsic block size of the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsBlockIoPeimReadBlocks2 (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,\r
+ IN UINTN DeviceIndex,\r
+ IN EFI_PEI_LBA StartLBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UFS_PEIM_HC_PRIVATE_DATA *Private; \r
+\r
+ Status = EFI_SUCCESS;\r
+ Private = GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This);\r
+\r
+ Status = UfsBlockIoPeimReadBlocks (\r
+ PeiServices,\r
+ &Private->BlkIoPpi,\r
+ DeviceIndex,\r
+ StartLBA,\r
+ BufferSize,\r
+ Buffer\r
+ );\r
+ return Status;\r
+}\r
+\r
/**\r
The user code starts with this function.\r
\r
break;\r
}\r
\r
- Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;\r
- Private->UfsHcBase = MmioBase;\r
+ Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;\r
+ Private->BlkIo2PpiList.Ppi = &Private->BlkIo2Ppi;\r
+ Private->UfsHcBase = MmioBase;\r
\r
//\r
// Initialize the memory pool which will be used in all transactions.\r
\r
#include <Ppi/UfsHostController.h>\r
#include <Ppi/BlockIo.h>\r
+#include <Ppi/BlockIo2.h>\r
\r
#include <Library/DebugLib.h>\r
#include <Library/BaseLib.h>\r
UFS_PEIM_MEM_POOL *Pool;\r
\r
EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi;\r
+ EFI_PEI_RECOVERY_BLOCK_IO2_PPI BlkIo2Ppi;\r
EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList;\r
- EFI_PEI_BLOCK_IO_MEDIA Media[UFS_PEIM_MAX_LUNS];\r
+ EFI_PEI_PPI_DESCRIPTOR BlkIo2PpiList;\r
+ EFI_PEI_BLOCK_IO2_MEDIA Media[UFS_PEIM_MAX_LUNS];\r
\r
UINTN UfsHcBase;\r
UINT32 Capabilities;\r
#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)\r
\r
#define GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS(a) CR (a, UFS_PEIM_HC_PRIVATE_DATA, BlkIoPpi, UFS_PEIM_HC_SIG)\r
+#define GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS2(a) CR (a, UFS_PEIM_HC_PRIVATE_DATA, BlkIo2Ppi, UFS_PEIM_HC_SIG)\r
\r
#define UFS_SCSI_OP_LENGTH_SIX 0x6\r
#define UFS_SCSI_OP_LENGTH_TEN 0xa\r
OUT VOID *Buffer\r
);\r
\r
+/**\r
+ Gets the count of block I/O devices that one specific block driver detects.\r
+\r
+ This function is used for getting the count of block I/O devices that one \r
+ specific block driver detects. To the PEI ATAPI driver, it returns the number\r
+ of all the detected ATAPI devices it detects during the enumeration process. \r
+ To the PEI legacy floppy driver, it returns the number of all the legacy \r
+ devices it finds during its enumeration process. If no device is detected, \r
+ then the function will return zero. \r
+ \r
+ @param[in] PeiServices General-purpose services that are available \r
+ to every PEIM.\r
+ @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI \r
+ instance.\r
+ @param[out] NumberBlockDevices The number of block I/O devices discovered.\r
+\r
+ @retval EFI_SUCCESS The operation performed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsBlockIoPeimGetDeviceNo2 (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,\r
+ OUT UINTN *NumberBlockDevices\r
+ );\r
+\r
+/**\r
+ Gets a block device's media information.\r
+\r
+ This function will provide the caller with the specified block device's media \r
+ information. If the media changes, calling this function will update the media \r
+ information accordingly.\r
+\r
+ @param[in] PeiServices General-purpose services that are available to every\r
+ PEIM\r
+ @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.\r
+ @param[in] DeviceIndex Specifies the block device to which the function wants \r
+ to talk. Because the driver that implements Block I/O \r
+ PPIs will manage multiple block devices, the PPIs that \r
+ want to talk to a single device must specify the \r
+ device index that was assigned during the enumeration\r
+ process. This index is a number from one to \r
+ NumberBlockDevices.\r
+ @param[out] MediaInfo The media information of the specified block media. \r
+ The caller is responsible for the ownership of this \r
+ data structure.\r
+\r
+ @par Note: \r
+ The MediaInfo structure describes an enumeration of possible block device \r
+ types. This enumeration exists because no device paths are actually passed \r
+ across interfaces that describe the type or class of hardware that is publishing \r
+ the block I/O interface. This enumeration will allow for policy decisions\r
+ in the Recovery PEIM, such as "Try to recover from legacy floppy first, \r
+ LS-120 second, CD-ROM third." If there are multiple partitions abstracted \r
+ by a given device type, they should be reported in ascending order; this \r
+ order also applies to nested partitions, such as legacy MBR, where the \r
+ outermost partitions would have precedence in the reporting order. The \r
+ same logic applies to systems such as IDE that have precedence relationships \r
+ like "Master/Slave" or "Primary/Secondary". The master device should be \r
+ reported first, the slave second.\r
+ \r
+ @retval EFI_SUCCESS Media information about the specified block device \r
+ was obtained successfully.\r
+ @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware \r
+ error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsBlockIoPeimGetMediaInfo2 (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,\r
+ IN UINTN DeviceIndex,\r
+ OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo\r
+ );\r
+\r
+/**\r
+ Reads the requested number of blocks from the specified block device.\r
+\r
+ The function reads the requested number of blocks from the device. All the \r
+ blocks are read, or an error is returned. If there is no media in the device,\r
+ the function returns EFI_NO_MEDIA.\r
+\r
+ @param[in] PeiServices General-purpose services that are available to \r
+ every PEIM.\r
+ @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.\r
+ @param[in] DeviceIndex Specifies the block device to which the function wants \r
+ to talk. Because the driver that implements Block I/O \r
+ PPIs will manage multiple block devices, PPIs that \r
+ want to talk to a single device must specify the device \r
+ index that was assigned during the enumeration process. \r
+ This index is a number from one to NumberBlockDevices.\r
+ @param[in] StartLBA The starting logical block address (LBA) to read from\r
+ on the device\r
+ @param[in] BufferSize The size of the Buffer in bytes. This number must be\r
+ a multiple of the intrinsic block size of the device.\r
+ @param[out] Buffer A pointer to the destination buffer for the data.\r
+ The caller is responsible for the ownership of the \r
+ buffer.\r
+ \r
+ @retval EFI_SUCCESS The data was read correctly from the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting \r
+ to perform the read operation.\r
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not \r
+ valid, or the buffer is not properly aligned.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of\r
+ the intrinsic block size of the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsBlockIoPeimReadBlocks2 (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,\r
+ IN UINTN DeviceIndex,\r
+ IN EFI_PEI_LBA StartLBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ );\r
+\r
/**\r
Initialize the memory management pool for the host controller.\r
\r