]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h
MdeModulePkg: Add UFS (Universal Flash Storage) Stack
[mirror_edk2.git] / MdeModulePkg / Bus / Ufs / UfsBlockIoPei / UfsBlockIoPei.h
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h
new file mode 100644 (file)
index 0000000..835b9c6
--- /dev/null
@@ -0,0 +1,434 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _UFS_BLOCK_IO_PEI_H_\r
+#define _UFS_BLOCK_IO_PEI_H_\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Ppi/UfsHostController.h>\r
+#include <Ppi/BlockIo.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+\r
+#include <IndustryStandard/Scsi.h>\r
+\r
+#include "UfsHci.h"\r
+#include "UfsHcMem.h"\r
+\r
+#define UFS_PEIM_HC_SIG             SIGNATURE_32 ('U', 'F', 'S', 'H')\r
+\r
+#define UFS_PEIM_MAX_LUNS           8\r
+\r
+typedef struct {\r
+  UINT8    Lun[UFS_PEIM_MAX_LUNS];\r
+  UINT16   BitMask:12;              // Bit 0~7 is for common luns. Bit 8~11 is reserved for those well known luns\r
+  UINT16   Rsvd:4;\r
+} UFS_PEIM_EXPOSED_LUNS;\r
+\r
+typedef struct {\r
+  ///\r
+  /// The timeout, in 100 ns units, to use for the execution of this SCSI\r
+  /// Request Packet. A Timeout value of 0 means that this function\r
+  /// will wait indefinitely for the SCSI Request Packet to execute. If\r
+  /// Timeout is greater than zero, then this function will return\r
+  /// EFI_TIMEOUT if the time required to execute the SCSI\r
+  /// Request Packet is greater than Timeout.\r
+  ///\r
+  UINT64 Timeout;\r
+  ///\r
+  /// A pointer to the data buffer to transfer between the SCSI\r
+  /// controller and the SCSI device for read and bidirectional commands.\r
+  ///\r
+  VOID   *InDataBuffer;\r
+  ///\r
+  /// A pointer to the data buffer to transfer between the SCSI\r
+  /// controller and the SCSI device for write or bidirectional commands.\r
+  ///\r
+  VOID   *OutDataBuffer;\r
+  ///\r
+  /// A pointer to the sense data that was generated by the execution of\r
+  /// the SCSI Request Packet.\r
+  ///\r
+  VOID   *SenseData;\r
+  ///\r
+  /// A pointer to buffer that contains the Command Data Block to\r
+  /// send to the SCSI device specified by Target and Lun.\r
+  ///\r
+  VOID   *Cdb;\r
+  ///\r
+  /// On Input, the size, in bytes, of InDataBuffer. On output, the\r
+  /// number of bytes transferred between the SCSI controller and the SCSI device.\r
+  ///\r
+  UINT32 InTransferLength;\r
+  ///\r
+  /// On Input, the size, in bytes of OutDataBuffer. On Output, the\r
+  /// Number of bytes transferred between SCSI Controller and the SCSI device.\r
+  ///\r
+  UINT32 OutTransferLength;\r
+  ///\r
+  /// The length, in bytes, of the buffer Cdb. The standard values are 6,\r
+  /// 10, 12, and 16, but other values are possible if a variable length CDB is used.\r
+  ///\r
+  UINT8  CdbLength;\r
+  ///\r
+  /// The direction of the data transfer. 0 for reads, 1 for writes. A\r
+  /// value of 2 is Reserved for Bi-Directional SCSI commands.\r
+  ///\r
+  UINT8  DataDirection;\r
+  ///\r
+  /// On input, the length in bytes of the SenseData buffer. On\r
+  /// output, the number of bytes written to the SenseData buffer.\r
+  ///\r
+  UINT8  SenseDataLength;\r
+} UFS_SCSI_REQUEST_PACKET;\r
+\r
+typedef struct _UFS_PEIM_HC_PRIVATE_DATA {  \r
+  UINT32                            Signature;\r
+  EFI_HANDLE                        Controller;\r
+\r
+  UFS_PEIM_MEM_POOL                 *Pool;\r
+\r
+  EFI_PEI_RECOVERY_BLOCK_IO_PPI     BlkIoPpi;\r
+  EFI_PEI_PPI_DESCRIPTOR            BlkIoPpiList;\r
+  EFI_PEI_BLOCK_IO_MEDIA            Media[UFS_PEIM_MAX_LUNS];\r
+\r
+  UINTN                             UfsHcBase;\r
+  UINT32                            Capabilities;\r
+\r
+  UINT8                             TaskTag;\r
+\r
+  VOID                              *UtpTrlBase;\r
+  UINT8                             Nutrs;\r
+  VOID                              *UtpTmrlBase;\r
+  UINT8                             Nutmrs;\r
+\r
+  UFS_PEIM_EXPOSED_LUNS             Luns;\r
+} UFS_PEIM_HC_PRIVATE_DATA;\r
+\r
+#define UFS_TIMEOUT                 MultU64x32((UINT64)(3), 10000000)\r
+\r
+#define ROUNDUP8(x) (((x) % 8 == 0) ? (x) : ((x) / 8 + 1) * 8)\r
+\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
+\r
+#define UFS_SCSI_OP_LENGTH_SIX      0x6\r
+#define UFS_SCSI_OP_LENGTH_TEN      0xa\r
+#define UFS_SCSI_OP_LENGTH_SIXTEEN  0x10\r
+\r
+typedef struct _UFS_DEVICE_MANAGEMENT_REQUEST_PACKET {\r
+  UINT64                            Timeout;\r
+  VOID                              *InDataBuffer;\r
+  VOID                              *OutDataBuffer;\r
+  UINT8                             Opcode;\r
+  UINT8                             DescId;\r
+  UINT8                             Index;\r
+  UINT8                             Selector;\r
+  UINT32                            InTransferLength;\r
+  UINT32                            OutTransferLength;\r
+  UINT8                             DataDirection;\r
+  UINT8                             Ocs;\r
+} UFS_DEVICE_MANAGEMENT_REQUEST_PACKET;\r
+\r
+/**\r
+  Sends a UFS-supported SCSI Request Packet to a UFS device that is attached to the UFS host controller.\r
+\r
+  @param[in]      Private       The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
+  @param[in]      Lun           The LUN of the UFS device to send the SCSI Request Packet.\r
+  @param[in, out] Packet        A pointer to the SCSI Request Packet to send to a specified Lun of the\r
+                                UFS device.\r
+\r
+  @retval EFI_SUCCESS           The SCSI Request Packet was sent by the host. For bi-directional\r
+                                commands, InTransferLength bytes were transferred from\r
+                                InDataBuffer. For write and bi-directional commands,\r
+                                OutTransferLength bytes were transferred by\r
+                                OutDataBuffer.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to send the SCSI Request\r
+                                Packet.\r
+  @retval EFI_OUT_OF_RESOURCES  The resource for transfer is not available.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the SCSI Request Packet to execute.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsExecScsiCmds (\r
+  IN     UFS_PEIM_HC_PRIVATE_DATA      *Private,\r
+  IN     UINT8                         Lun,\r
+  IN OUT UFS_SCSI_REQUEST_PACKET       *Packet\r
+  );\r
+\r
+/**\r
+  Initialize the UFS host controller.\r
+\r
+  @param[in] Private                 The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
+\r
+  @retval EFI_SUCCESS                The Ufs Host Controller is initialized successfully.\r
+  @retval Others                     A device error occurred while initializing the controller.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsControllerInit (\r
+  IN  UFS_PEIM_HC_PRIVATE_DATA       *Private\r
+  );\r
+\r
+/**\r
+  Stop the UFS host controller.\r
+\r
+  @param[in] Private                 The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
+\r
+  @retval EFI_SUCCESS                The Ufs Host Controller is stopped successfully.\r
+  @retval Others                     A device error occurred while stopping the controller.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsControllerStop (\r
+  IN  UFS_PEIM_HC_PRIVATE_DATA       *Private\r
+  );\r
+\r
+/**\r
+  Set specified flag to 1 on a UFS device.\r
+\r
+  @param[in]  Private           The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
+  @param[in]  FlagId            The ID of flag to be set.\r
+\r
+  @retval EFI_SUCCESS           The flag was set successfully.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to set the flag.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of setting the flag.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsSetFlag (\r
+  IN  UFS_PEIM_HC_PRIVATE_DATA     *Private,\r
+  IN  UINT8                        FlagId\r
+  );\r
+\r
+/**\r
+  Read or write specified device descriptor of a UFS device.\r
+\r
+  @param[in]      Private       The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
+  @param[in]      Read          The boolean variable to show r/w direction.\r
+  @param[in]      DescId        The ID of device descriptor.\r
+  @param[in]      Index         The Index of device descriptor.\r
+  @param[in]      Selector      The Selector of device descriptor.\r
+  @param[in, out] Descriptor    The buffer of device descriptor to be read or written.\r
+  @param[in]      DescSize      The size of device descriptor buffer.\r
+\r
+  @retval EFI_SUCCESS           The device descriptor was read/written successfully.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the device descriptor.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the device descriptor.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsRwDeviceDesc (\r
+  IN     UFS_PEIM_HC_PRIVATE_DATA     *Private,\r
+  IN     BOOLEAN                      Read,\r
+  IN     UINT8                        DescId,\r
+  IN     UINT8                        Index,\r
+  IN     UINT8                        Selector,\r
+  IN OUT VOID                         *Descriptor,\r
+  IN     UINT32                       DescSize\r
+  );\r
+\r
+/**\r
+  Sends NOP IN cmd to a UFS device for initialization process request.\r
+  For more details, please refer to UFS 2.0 spec Figure 13.3.\r
+\r
+  @param[in]  Private           The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.\r
+\r
+  @retval EFI_SUCCESS           The NOP IN command was sent by the host. The NOP OUT response was\r
+                                received successfully.\r
+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to execute NOP IN command.\r
+  @retval EFI_OUT_OF_RESOURCES  The resource for transfer is not available.\r
+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the NOP IN command to execute.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsExecNopCmds (\r
+  IN  UFS_PEIM_HC_PRIVATE_DATA       *Private\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_IO_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
+UfsBlockIoPeimGetDeviceNo (\r
+  IN  EFI_PEI_SERVICES               **PeiServices,\r
+  IN  EFI_PEI_RECOVERY_BLOCK_IO_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_IO_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
+UfsBlockIoPeimGetMediaInfo (\r
+  IN  EFI_PEI_SERVICES               **PeiServices,\r
+  IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI  *This,\r
+  IN  UINTN                          DeviceIndex,\r
+  OUT EFI_PEI_BLOCK_IO_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_IO_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
+UfsBlockIoPeimReadBlocks (\r
+  IN  EFI_PEI_SERVICES               **PeiServices,\r
+  IN  EFI_PEI_RECOVERY_BLOCK_IO_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
+  @param  Private               The Ufs Peim driver private data.\r
+\r
+  @retval EFI_SUCCESS           The memory pool is initialized.\r
+  @retval Others                Fail to init the memory pool.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsPeimInitMemPool (\r
+  IN  UFS_PEIM_HC_PRIVATE_DATA      *Private\r
+  );\r
+\r
+/**\r
+  Allocate some memory from the host controller's memory pool\r
+  which can be used to communicate with host controller.\r
+  \r
+  @param  Pool      The host controller's memory pool.\r
+  @param  Size      Size of the memory to allocate.\r
+\r
+  @return The allocated memory or NULL.\r
+\r
+**/\r
+VOID *\r
+UfsPeimAllocateMem (\r
+  IN  UFS_PEIM_MEM_POOL        *Pool,\r
+  IN  UINTN                    Size\r
+  );\r
+\r
+/**\r
+  Free the allocated memory back to the memory pool.\r
+\r
+  @param  Pool           The memory pool of the host controller.\r
+  @param  Mem            The memory to free.\r
+  @param  Size           The size of the memory to free.\r
+\r
+**/\r
+VOID\r
+UfsPeimFreeMem (\r
+  IN UFS_PEIM_MEM_POOL    *Pool,\r
+  IN VOID                 *Mem,\r
+  IN UINTN                Size\r
+  );\r
+\r
+#endif\r