]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/Ufs: Refine EDKII_UFS_HOST_CONTROLLER_PROTOCOL interface
authorFeng Tian <feng.tian@intel.com>
Thu, 28 May 2015 07:42:05 +0000 (07:42 +0000)
committererictian <erictian@Edk2>
Thu, 28 May 2015 07:42:05 +0000 (07:42 +0000)
The EDKII_UFS_HOST_CONTROLLER_PROTOCOL is refined to provide
interfaces accessing UFS host controller MMIO register.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17533 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c
MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h
MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h
MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c
MdeModulePkg/Include/Protocol/UfsHostController.h

index 586a52b380440b87dd254cbe23062a723959cd33..12643689b9f4cb856113b7ae029c8ccef048b325 100644 (file)
@@ -2,7 +2,7 @@
   UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller\r
   MMIO base, to upper layer UFS drivers.\r
 \r
-  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2015, 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
@@ -39,9 +39,12 @@ UFS_HOST_CONTROLLER_PRIVATE_DATA gUfsHcTemplate = {
     UfsHcFreeBuffer,\r
     UfsHcMap,\r
     UfsHcUnmap,\r
-    UfsHcFlush\r
+    UfsHcFlush,\r
+    UfsHcMmioRead,\r
+    UfsHcMmioWrite\r
   },\r
   NULL,                           // PciIo\r
+  0,                              // BarIndex\r
   0                               // PciAttributes\r
 };\r
 \r
@@ -64,25 +67,32 @@ UfsHcGetMmioBar (
   UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;\r
   EFI_PCI_IO_PROTOCOL               *PciIo;\r
   EFI_STATUS                        Status;\r
+  UINT8                             BarIndex;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;\r
 \r
   if ((This == NULL) || (MmioBar == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);\r
-  PciIo   = Private->PciIo;\r
-\r
-  Status = PciIo->Pci.Read (\r
-                        PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        PCI_BASE_ADDRESSREG_OFFSET,\r
-                        sizeof (UINT32),\r
-                        MmioBar\r
-                        );\r
+  BarDesc  = NULL;\r
+  Private  = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);\r
+  PciIo    = Private->PciIo;\r
+  BarIndex = Private->BarIndex;\r
 \r
-  if (!EFI_ERROR (Status)) {\r
-    *MmioBar &= (UINTN)~0xF;\r
+  Status = PciIo->GetBarAttributes (\r
+                    PciIo,\r
+                    BarIndex,\r
+                    NULL,\r
+                    (VOID**) &BarDesc\r
+                    );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
+\r
+  *MmioBar = (UINTN)BarDesc->AddrRangeMin;\r
+\r
+  FreePool (BarDesc);\r
+\r
   return Status;\r
 }\r
 \r
@@ -272,6 +282,90 @@ UfsHcFlush (
   return Status;\r
 }\r
 \r
+/**                                                                 \r
+  Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.\r
+\r
+  @param  This                  A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.\r
+  @param  Width                 Signifies the width of the memory operations.\r
+  @param  Offset                The offset within the UFS Host Controller MMIO space to start the\r
+                                memory operation.\r
+  @param  Count                 The number of memory operations to perform.\r
+  @param  Buffer                For read operations, the destination buffer to store the results.\r
+                                For write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS           The data was read from or written to the UFS host controller.\r
+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not\r
+                                valid for the UFS Host Controller memory space.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsHcMmioRead (\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This,\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH  Width,\r
+  IN     UINT64                                    Offset,\r
+  IN     UINTN                                     Count,\r
+  IN OUT VOID                                      *Buffer\r
+  )\r
+{\r
+  UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;\r
+  EFI_PCI_IO_PROTOCOL               *PciIo;\r
+  EFI_STATUS                        Status;\r
+  UINT8                             BarIndex;\r
+\r
+  Private  = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);\r
+  PciIo    = Private->PciIo;\r
+  BarIndex = Private->BarIndex;\r
+\r
+  Status   = PciIo->Mem.Read (PciIo, (EFI_PCI_IO_PROTOCOL_WIDTH)Width, BarIndex, Offset, Count, Buffer);\r
+\r
+  return Status;\r
+}\r
+\r
+/**                                                                 \r
+  Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.\r
+\r
+  @param  This                  A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.\r
+  @param  Width                 Signifies the width of the memory operations.\r
+  @param  Offset                The offset within the UFS Host Controller MMIO space to start the\r
+                                memory operation.\r
+  @param  Count                 The number of memory operations to perform.\r
+  @param  Buffer                For read operations, the destination buffer to store the results.\r
+                                For write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS           The data was read from or written to the UFS host controller.\r
+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not\r
+                                valid for the UFS Host Controller memory space.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsHcMmioWrite (\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This,\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH  Width,\r
+  IN     UINT64                                    Offset,\r
+  IN     UINTN                                     Count,\r
+  IN OUT VOID                                      *Buffer\r
+  )\r
+{\r
+  UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;\r
+  EFI_PCI_IO_PROTOCOL               *PciIo;\r
+  EFI_STATUS                        Status;\r
+  UINT8                             BarIndex;\r
+\r
+  Private  = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);\r
+  PciIo    = Private->PciIo;\r
+  BarIndex = Private->BarIndex;\r
+\r
+  Status   = PciIo->Mem.Write (PciIo, (EFI_PCI_IO_PROTOCOL_WIDTH)Width, BarIndex, Offset, Count, Buffer);\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Tests to see if this driver supports a given controller. If a child device is provided,\r
   it further tests to see if this driver supports creating a handle for the specified child device.\r
@@ -468,10 +562,13 @@ UfsHcDriverBindingStart (
   EFI_PCI_IO_PROTOCOL               *PciIo;\r
   UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;\r
   UINT64                            Supports;\r
+  UINT8                             BarIndex;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;\r
 \r
   PciIo    = NULL;\r
   Private  = NULL;\r
   Supports = 0;\r
+  BarDesc  = NULL;\r
 \r
   //\r
   // Now test and open the EfiPciIoProtocol\r
@@ -507,6 +604,28 @@ UfsHcDriverBindingStart (
 \r
   Private->PciIo = PciIo;\r
 \r
+  for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {\r
+    Status = PciIo->GetBarAttributes (\r
+                      PciIo,\r
+                      BarIndex,\r
+                      NULL,\r
+                      (VOID**) &BarDesc\r
+                      );\r
+    if (Status == EFI_UNSUPPORTED) {\r
+      continue;\r
+    } else if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
+      Private->BarIndex = BarIndex;\r
+      FreePool (BarDesc);\r
+      break;\r
+    }\r
+\r
+    FreePool (BarDesc);\r
+  }\r
+\r
   Status = PciIo->Attributes (\r
                     PciIo,\r
                     EfiPciIoAttributeOperationGet,\r
index f3b7eab24acdc9b0cb198d7437e7a311db8ad36e..89f19feb7aa725322f5c52dbdaa708428626e4b4 100644 (file)
@@ -2,7 +2,7 @@
   UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller\r
   MMIO base, to upper layer UFS drivers.\r
 \r
-  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2015, 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
@@ -19,6 +19,7 @@
 #include <Uefi.h>\r
 \r
 #include <IndustryStandard/Pci.h>\r
+#include <IndustryStandard/Acpi.h>\r
 \r
 #include <Protocol/ComponentName.h>\r
 #include <Protocol/ComponentName2.h>\r
@@ -56,6 +57,7 @@ struct _UFS_HOST_CONTROLLER_PRIVATE_DATA {
 \r
   EDKII_UFS_HOST_CONTROLLER_PROTOCOL UfsHc;\r
   EFI_PCI_IO_PROTOCOL                *PciIo;  \r
+  UINT8                              BarIndex;\r
   UINT64                             PciAttributes;\r
 };\r
 \r
@@ -450,4 +452,60 @@ UfsHcFlush (
   IN  EDKII_UFS_HOST_CONTROLLER_PROTOCOL   *This\r
   );\r
 \r
+/**                                                                 \r
+  Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.\r
+\r
+  @param  This                  A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.\r
+  @param  Width                 Signifies the width of the memory operations.\r
+  @param  Offset                The offset within the UFS Host Controller MMIO space to start the\r
+                                memory operation.\r
+  @param  Count                 The number of memory operations to perform.\r
+  @param  Buffer                For read operations, the destination buffer to store the results.\r
+                                For write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS           The data was read from or written to the UFS host controller.\r
+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not\r
+                                valid for the UFS Host Controller memory space.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsHcMmioRead (\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This,\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH  Width,\r
+  IN     UINT64                                    Offset,\r
+  IN     UINTN                                     Count,\r
+  IN OUT VOID                                      *Buffer\r
+  );\r
+\r
+/**                                                                 \r
+  Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.\r
+\r
+  @param  This                  A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.\r
+  @param  Width                 Signifies the width of the memory operations.\r
+  @param  Offset                The offset within the UFS Host Controller MMIO space to start the\r
+                                memory operation.\r
+  @param  Count                 The number of memory operations to perform.\r
+  @param  Buffer                For read operations, the destination buffer to store the results.\r
+                                For write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS           The data was read from or written to the UFS host controller.\r
+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not\r
+                                valid for the UFS Host Controller memory space.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UfsHcMmioWrite (\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This,\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH  Width,\r
+  IN     UINT64                                    Offset,\r
+  IN     UINTN                                     Count,\r
+  IN OUT VOID                                      *Buffer\r
+  );\r
+\r
 #endif\r
index c435fe19aa0aa173d9d52f71bc2696da2458f4dc..3d8e3510bd77b06792b1545d81c408539044a3ac 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2015, 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
@@ -27,7 +27,6 @@
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DevicePathLib.h>\r
-#include <Library/IoLib.h>\r
 #include <Library/TimerLib.h>\r
 \r
 #include "UfsPassThruHci.h"\r
index 21b8e6c0c23cfc45f9184e2db9dc69bbc7b922f8..c90c72f9150dc8931e3ae5e2526262af3982980f 100644 (file)
@@ -52,7 +52,6 @@
   UefiDriverEntryPoint\r
   DebugLib\r
   DevicePathLib\r
-  IoLib\r
   TimerLib\r
 \r
 [Protocols]\r
index 4cc32f07273f05ee97aa9812cad088aab74dbe7c..9f9abab40fded3ea72fc10e08669bcdfcd04ea38 100644 (file)
@@ -2,7 +2,7 @@
   UfsPassThruDxe driver is used to produce EFI_EXT_SCSI_PASS_THRU protocol interface\r
   for upper layer application to execute UFS-supported SCSI cmds.\r
 \r
-  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2015, 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
 \r
 #include "UfsPassThru.h"\r
 \r
+/**\r
+  Read 32bits data from specified UFS MMIO register.\r
+\r
+  @param[in]  Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
+  @param[in]  Offset        The offset within the UFS Host Controller MMIO space to start\r
+                            the memory operation.\r
+  @param[out] Value         The data buffer to store.\r
+\r
+  @retval EFI_TIMEOUT       The operation is time out.\r
+  @retval EFI_SUCCESS       The operation succeeds.\r
+  @retval Others            The operation fails.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsMmioRead32 (\r
+  IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
+  IN     UINTN                        Offset,\r
+     OUT UINT32                       *Value\r
+  )\r
+{\r
+  EDKII_UFS_HOST_CONTROLLER_PROTOCOL  *UfsHc;\r
+  EFI_STATUS                          Status;\r
+\r
+  UfsHc = Private->UfsHostController;\r
+\r
+  Status = UfsHc->Read (UfsHc, EfiUfsHcWidthUint32, Offset, 1, Value);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Write 32bits data to specified UFS MMIO register.\r
+\r
+  @param[in] Private        The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
+  @param[in] Offset         The offset within the UFS Host Controller MMIO space to start\r
+                            the memory operation.\r
+  @param[in] Value          The data to write.\r
+\r
+  @retval EFI_TIMEOUT       The operation is time out.\r
+  @retval EFI_SUCCESS       The operation succeeds.\r
+  @retval Others            The operation fails.\r
+\r
+**/\r
+EFI_STATUS\r
+UfsMmioWrite32 (\r
+  IN  UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
+  IN  UINTN                        Offset,\r
+  IN  UINT32                       Value\r
+  )\r
+{\r
+  EDKII_UFS_HOST_CONTROLLER_PROTOCOL  *UfsHc;\r
+  EFI_STATUS                          Status;\r
+\r
+  UfsHc = Private->UfsHostController;\r
+\r
+  Status = UfsHc->Write (UfsHc, EfiUfsHcWidthUint32, Offset, 1, &Value);\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Wait for the value of the specified system memory set to the test value.\r
 \r
-  @param  Address           The system memory address to test.\r
-  @param  MaskValue         The mask value of memory.\r
-  @param  TestValue         The test value of memory.\r
-  @param  Timeout           The time out value for wait memory set, uses 100ns as a unit.\r
+  @param[in]  Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.\r
+  @param[in]  Offset        The offset within the UFS Host Controller MMIO space to start\r
+                            the memory operation.\r
+  @param[in]  MaskValue     The mask value of memory.\r
+  @param[in]  TestValue     The test value of memory.\r
+  @param[in]  Timeout       The time out value for wait memory set, uses 100ns as a unit.\r
 \r
   @retval EFI_TIMEOUT       The system memory setting is time out.\r
   @retval EFI_SUCCESS       The system memory is correct set.\r
+  @retval Others            The operation fails.\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 UfsWaitMemSet (\r
-  IN  UINTN                     Address,\r
-  IN  UINT32                    MaskValue,\r
-  IN  UINT32                    TestValue,\r
-  IN  UINT64                    Timeout\r
+  IN  UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
+  IN  UINTN                        Offset,\r
+  IN  UINT32                       MaskValue,\r
+  IN  UINT32                       TestValue,\r
+  IN  UINT64                       Timeout\r
   )\r
 {\r
   UINT32     Value;\r
   UINT64     Delay;\r
   BOOLEAN    InfiniteWait;\r
+  EFI_STATUS Status;\r
 \r
   if (Timeout == 0) {\r
     InfiniteWait = TRUE;\r
@@ -52,7 +116,12 @@ UfsWaitMemSet (
     //\r
     // Access PCI MMIO space to see if the value is the tested one.\r
     //\r
-    Value = MmioRead32 (Address) & MaskValue;\r
+    Status = UfsMmioRead32 (Private, Offset, &Value);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    Value &= MaskValue;\r
 \r
     if (Value == TestValue) {\r
       return EFI_SUCCESS;\r
@@ -712,26 +781,33 @@ UfsFindAvailableSlotInTmrl (
   @param[in]  Slot          The slot to be started.\r
 \r
 **/\r
-VOID\r
+EFI_STATUS\r
 UfsStartExecCmd (\r
   IN  UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
   IN  UINT8                        Slot\r
   ) \r
 {\r
-  UINTN         UfsHcBase;\r
-  UINTN         Address;\r
   UINT32        Data;\r
+  EFI_STATUS    Status;\r
 \r
-  UfsHcBase = Private->UfsHcBase;\r
+  Status = UfsMmioRead32 (Private, UFS_HC_UTRLRSR_OFFSET, &Data);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-  Address = UfsHcBase + UFS_HC_UTRLRSR_OFFSET;  \r
-  Data    = MmioRead32 (Address);\r
   if ((Data & UFS_HC_UTRLRSR) != UFS_HC_UTRLRSR) {\r
-    MmioWrite32 (Address, UFS_HC_UTRLRSR);\r
+    Status = UfsMmioWrite32 (Private, UFS_HC_UTRLRSR_OFFSET, UFS_HC_UTRLRSR);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
 \r
-  Address = UfsHcBase + UFS_HC_UTRLDBR_OFFSET;\r
-  MmioWrite32 (Address, BIT0 << Slot);\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -741,25 +817,33 @@ UfsStartExecCmd (
   @param[in]  Slot          The slot to be stop.\r
 \r
 **/\r
-VOID\r
+EFI_STATUS\r
 UfsStopExecCmd (\r
   IN  UFS_PASS_THRU_PRIVATE_DATA   *Private,\r
   IN  UINT8                        Slot\r
   ) \r
 {\r
-  UINTN         UfsHcBase;\r
-  UINTN         Address;\r
   UINT32        Data;\r
+  EFI_STATUS    Status;\r
 \r
-  UfsHcBase = Private->UfsHcBase;\r
+  Status = UfsMmioRead32 (Private, UFS_HC_UTRLDBR_OFFSET, &Data);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-  Address = UfsHcBase + UFS_HC_UTRLDBR_OFFSET;  \r
-  Data    = MmioRead32 (Address);\r
   if ((Data & (BIT0 << Slot)) != 0) {\r
-    Address = UfsHcBase + UFS_HC_UTRLCLR_OFFSET;  \r
-    Data    = MmioRead32 (Address);\r
-    MmioWrite32 (Address, (Data & ~(BIT0 << Slot)));\r
+    Status = UfsMmioRead32 (Private, UFS_HC_UTRLCLR_OFFSET, &Data);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    Status = UfsMmioWrite32 (Private, UFS_HC_UTRLCLR_OFFSET, Data & ~(BIT0 << Slot));\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
   }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -793,7 +877,6 @@ UfsRwDeviceDesc (
   UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
   UINT8                                Slot;\r
   UTP_TRD                              *Trd;\r
-  UINTN                                Address;\r
   UTP_QUERY_RESP_UPIU                  *QueryResp;\r
   UINT32                               CmdDescSize;\r
   UINT16                               ReturnDataSize;\r
@@ -852,8 +935,7 @@ UfsRwDeviceDesc (
   //\r
   // Wait for the completion of the transfer request.\r
   //  \r
-  Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;  \r
-  Status = UfsWaitMemSet (Address, BIT0, 0, Packet.Timeout);\r
+  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet.Timeout);\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
@@ -922,7 +1004,6 @@ UfsRwAttributes (
   UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
   UINT8                                Slot;\r
   UTP_TRD                              *Trd;\r
-  UINTN                                Address;\r
   UTP_QUERY_RESP_UPIU                  *QueryResp;\r
   UINT32                               CmdDescSize;\r
   UINT32                               ReturnData;\r
@@ -977,8 +1058,7 @@ UfsRwAttributes (
   //\r
   // Wait for the completion of the transfer request.\r
   //  \r
-  Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;  \r
-  Status = UfsWaitMemSet (Address, BIT0, 0, Packet.Timeout);\r
+  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet.Timeout);\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
@@ -1038,7 +1118,6 @@ UfsRwFlags (
   UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;\r
   UINT8                                Slot;\r
   UTP_TRD                              *Trd;\r
-  UINTN                                Address;\r
   UTP_QUERY_RESP_UPIU                  *QueryResp;\r
   UINT32                               CmdDescSize;\r
   VOID                                 *CmdDescHost;\r
@@ -1103,8 +1182,7 @@ UfsRwFlags (
   //\r
   // Wait for the completion of the transfer request.\r
   //  \r
-  Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;  \r
-  Status = UfsWaitMemSet (Address, BIT0, 0, Packet.Timeout);\r
+  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet.Timeout);\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
@@ -1237,7 +1315,6 @@ UfsExecNopCmds (
   UTP_TRD                              *Trd;\r
   UTP_NOP_IN_UPIU                      *NopInUpiu;\r
   UINT32                               CmdDescSize;\r
-  UINTN                                Address;\r
   VOID                                 *CmdDescHost;\r
   VOID                                 *CmdDescMapping;\r
   EDKII_UFS_HOST_CONTROLLER_PROTOCOL   *UfsHc;\r
@@ -1272,8 +1349,7 @@ UfsExecNopCmds (
   //\r
   // Wait for the completion of the transfer request.\r
   //  \r
-  Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;  \r
-  Status = UfsWaitMemSet (Address, BIT0, 0, UFS_TIMEOUT);\r
+  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, UFS_TIMEOUT);\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
@@ -1328,7 +1404,6 @@ UfsExecScsiCmds (
   EFI_STATUS                           Status;\r
   UINT8                                Slot;\r
   UTP_TRD                              *Trd;\r
-  UINTN                                Address;\r
   UINT32                               CmdDescSize;\r
   UTP_RESPONSE_UPIU                    *Response;\r
   UINT16                               SenseDataLen;\r
@@ -1414,9 +1489,8 @@ UfsExecScsiCmds (
 \r
   //\r
   // Wait for the completion of the transfer request.\r
-  //  \r
-  Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;  \r
-  Status = UfsWaitMemSet (Address, BIT0, 0, Packet->Timeout);\r
+  // \r
+  Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet->Timeout);\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
@@ -1506,18 +1580,21 @@ UfsExecUicCommands (
   )\r
 {\r
   EFI_STATUS  Status;\r
-  UINTN       Address;\r
   UINT32      Data;\r
-  UINTN       UfsHcBase;\r
 \r
-  UfsHcBase = Private->UfsHcBase;\r
-  Address   = UfsHcBase + UFS_HC_IS_OFFSET;\r
-  Data      = MmioRead32 (Address);\r
+  Status = UfsMmioRead32 (Private, UFS_HC_IS_OFFSET, &Data);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   if ((Data & UFS_HC_IS_UCCS) == UFS_HC_IS_UCCS) {\r
     //\r
     // Clear IS.BIT10 UIC Command Completion Status (UCCS) at first.\r
     //\r
-    MmioWrite32 (Address, Data);\r
+    Status = UfsMmioWrite32 (Private, UFS_HC_IS_OFFSET, Data);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
   }\r
 \r
   //\r
@@ -1525,41 +1602,48 @@ UfsExecUicCommands (
   // only after all the UIC command argument registers (UICCMDARG1, UICCMDARG2 and UICCMDARG3)\r
   // are set.\r
   //\r
-  Address = UfsHcBase + UFS_HC_UCMD_ARG1_OFFSET;\r
-  MmioWrite32 (Address, Arg1);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG1_OFFSET, Arg1);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-  Address = UfsHcBase + UFS_HC_UCMD_ARG2_OFFSET;\r
-  MmioWrite32 (Address, Arg2);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG2_OFFSET, Arg2);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-  Address = UfsHcBase + UFS_HC_UCMD_ARG3_OFFSET;\r
-  MmioWrite32 (Address, Arg3);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG3_OFFSET, Arg3);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Host software shall only set the UICCMD if HCS.UCRDY is set to 1.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_STATUS_OFFSET;\r
-  Status = UfsWaitMemSet (Address, UFS_HC_HCS_UCRDY, UFS_HC_HCS_UCRDY, UFS_TIMEOUT);\r
+  Status = UfsWaitMemSet (Private, UFS_HC_STATUS_OFFSET, UFS_HC_HCS_UCRDY, UFS_HC_HCS_UCRDY, UFS_TIMEOUT);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  Address = UfsHcBase + UFS_HC_UIC_CMD_OFFSET;\r
-  MmioWrite32 (Address, (UINT32)UicOpcode);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UIC_CMD_OFFSET, (UINT32)UicOpcode);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\r
   // UFS 2.0 spec section 5.3.1 Offset:0x20 IS.Bit10 UIC Command Completion Status (UCCS)\r
   // This bit is set to '1' by the host controller upon completion of a UIC command. \r
   //\r
-  Address = UfsHcBase + UFS_HC_IS_OFFSET;\r
-  Data    = MmioRead32 (Address);\r
-  Status  = UfsWaitMemSet (Address, UFS_HC_IS_UCCS, UFS_HC_IS_UCCS, UFS_TIMEOUT);\r
+  Status  = UfsWaitMemSet (Private, UFS_HC_IS_OFFSET, UFS_HC_IS_UCCS, UFS_HC_IS_UCCS, UFS_TIMEOUT);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   if (UicOpcode != UfsUicDmeReset) {\r
-    Address = UfsHcBase + UFS_HC_UCMD_ARG2_OFFSET;\r
-    Data    = MmioRead32 (Address);\r
+    Status = UfsMmioRead32 (Private, UFS_HC_UCMD_ARG2_OFFSET, &Data);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
     if ((Data & 0xFF) != 0) {\r
       DEBUG_CODE_BEGIN();\r
         DumpUicCmdExecResult (UicOpcode, (UINT8)(Data & 0xFF));\r
@@ -1571,11 +1655,13 @@ UfsExecUicCommands (
   //\r
   // Check value of HCS.DP and make sure that there is a device attached to the Link.\r
   //\r
-  Address = UfsHcBase + UFS_HC_STATUS_OFFSET;  \r
-  Data    = MmioRead32 (Address);\r
+  Status = UfsMmioRead32 (Private, UFS_HC_STATUS_OFFSET, &Data);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   if ((Data & UFS_HC_HCS_DP) == 0) {\r
-    Address = UfsHcBase + UFS_HC_IS_OFFSET;\r
-    Status  = UfsWaitMemSet (Address, UFS_HC_IS_ULSS, UFS_HC_IS_ULSS, UFS_TIMEOUT);\r
+    Status  = UfsWaitMemSet (Private, UFS_HC_IS_OFFSET, UFS_HC_IS_ULSS, UFS_HC_IS_ULSS, UFS_TIMEOUT);\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -1694,7 +1780,6 @@ UfsEnableHostController (
   )\r
 {\r
   EFI_STATUS             Status;\r
-  UINTN                  Address;\r
   UINT32                 Data;\r
 \r
   //\r
@@ -1702,17 +1787,23 @@ UfsEnableHostController (
   //\r
   // Reinitialize the UFS host controller if HCE bit of HC register is set.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_ENABLE_OFFSET;\r
-  Data    = MmioRead32 (Address);\r
+  Status = UfsMmioRead32 (Private, UFS_HC_ENABLE_OFFSET, &Data);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   if ((Data & UFS_HC_HCE_EN) == UFS_HC_HCE_EN) {\r
     //\r
     // Write a 0 to the HCE register at first to disable the host controller.\r
     //\r
-    MmioWrite32 (Address, 0);\r
+    Status = UfsMmioWrite32 (Private, UFS_HC_ENABLE_OFFSET, 0);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
     //\r
     // Wait until HCE is read as '0' before continuing.\r
     //\r
-    Status = UfsWaitMemSet (Address, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);\r
+    Status = UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -1721,11 +1812,15 @@ UfsEnableHostController (
   //\r
   // Write a 1 to the HCE register to enable the UFS host controller.\r
   //\r
-  MmioWrite32 (Address, UFS_HC_HCE_EN);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   //\r
   // Wait until HCE is read as '1' before continuing.\r
   //\r
-  Status = UfsWaitMemSet (Address, UFS_HC_HCE_EN, UFS_HC_HCE_EN, UFS_TIMEOUT);\r
+  Status = UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, UFS_HC_HCE_EN, UFS_TIMEOUT);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -1789,7 +1884,6 @@ UfsInitTaskManagementRequestList (
   IN  UFS_PASS_THRU_PRIVATE_DATA     *Private\r
   )\r
 {\r
-  UINTN                  Address;\r
   UINT32                 Data;\r
   UINT8                  Nutmrs;\r
   VOID                   *CmdDescHost;\r
@@ -1803,8 +1897,12 @@ UfsInitTaskManagementRequestList (
   CmdDescHost    = NULL;\r
   CmdDescMapping = NULL;\r
   CmdDescPhyAddr = 0;\r
-  Address = Private->UfsHcBase + UFS_HC_CAP_OFFSET;  \r
-  Data    = MmioRead32 (Address);\r
+\r
+  Status = UfsMmioRead32 (Private, UFS_HC_CAP_OFFSET, &Data);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   Private->Capabilities = Data;\r
 \r
   //\r
@@ -1820,10 +1918,15 @@ UfsInitTaskManagementRequestList (
   // Program the UTP Task Management Request List Base Address and UTP Task Management\r
   // Request List Base Address with a 64-bit address allocated at step 6.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_UTMRLBA_OFFSET;  \r
-  MmioWrite32 (Address, (UINT32)(UINTN)CmdDescPhyAddr);\r
-  Address = Private->UfsHcBase + UFS_HC_UTMRLBAU_OFFSET;  \r
-  MmioWrite32 (Address, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTMRLBA_OFFSET, (UINT32)(UINTN)CmdDescPhyAddr);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTMRLBAU_OFFSET, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
   Private->UtpTmrlBase = CmdDescHost;\r
   Private->Nutmrs      = Nutmrs;\r
   Private->TmrlMapping = CmdDescMapping;\r
@@ -1832,8 +1935,10 @@ UfsInitTaskManagementRequestList (
   // Enable the UTP Task Management Request List by setting the UTP Task Management\r
   // Request List RunStop Register (UTMRLRSR) to '1'.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_UTMRLRSR_OFFSET;  \r
-  MmioWrite32 (Address, UFS_HC_UTMRLRSR);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTMRLRSR_OFFSET, UFS_HC_UTMRLRSR);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1852,7 +1957,6 @@ UfsInitTransferRequestList (
   IN  UFS_PASS_THRU_PRIVATE_DATA     *Private\r
   )\r
 {\r
-  UINTN                  Address;\r
   UINT32                 Data;\r
   UINT8                  Nutrs;\r
   VOID                   *CmdDescHost;\r
@@ -1866,8 +1970,12 @@ UfsInitTransferRequestList (
   CmdDescHost    = NULL;\r
   CmdDescMapping = NULL;\r
   CmdDescPhyAddr = 0;\r
-  Address = Private->UfsHcBase + UFS_HC_CAP_OFFSET;  \r
-  Data    = MmioRead32 (Address);\r
+\r
+  Status = UfsMmioRead32 (Private, UFS_HC_CAP_OFFSET, &Data);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   Private->Capabilities = Data;\r
 \r
   //\r
@@ -1883,10 +1991,16 @@ UfsInitTransferRequestList (
   // Program the UTP Transfer Request List Base Address and UTP Transfer Request List\r
   // Base Address with a 64-bit address allocated at step 8.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_UTRLBA_OFFSET;  \r
-  MmioWrite32 (Address, (UINT32)(UINTN)CmdDescPhyAddr);\r
-  Address = Private->UfsHcBase + UFS_HC_UTRLBAU_OFFSET;  \r
-  MmioWrite32 (Address, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTRLBA_OFFSET, (UINT32)(UINTN)CmdDescPhyAddr);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTRLBAU_OFFSET, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   Private->UtpTrlBase = CmdDescHost;\r
   Private->Nutrs      = Nutrs;  \r
   Private->TrlMapping = CmdDescMapping;\r
@@ -1895,8 +2009,10 @@ UfsInitTransferRequestList (
   // Enable the UTP Transfer Request List by setting the UTP Transfer Request List\r
   // RunStop Register (UTRLRSR) to '1'.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_UTRLRSR_OFFSET;  \r
-  MmioWrite32 (Address, UFS_HC_UTRLRSR);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTRLRSR_OFFSET, UFS_HC_UTRLRSR);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1960,35 +2076,44 @@ UfsControllerStop (
   )\r
 {\r
   EFI_STATUS             Status;\r
-  UINTN                  Address;\r
   UINT32                 Data;\r
 \r
   //\r
   // Enable the UTP Task Management Request List by setting the UTP Task Management\r
   // Request List RunStop Register (UTMRLRSR) to '1'.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_UTMRLRSR_OFFSET;  \r
-  MmioWrite32 (Address, 0);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTMRLRSR_OFFSET, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Enable the UTP Transfer Request List by setting the UTP Transfer Request List\r
   // RunStop Register (UTRLRSR) to '1'.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_UTRLRSR_OFFSET;  \r
-  MmioWrite32 (Address, 0);\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_UTRLRSR_OFFSET, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Write a 0 to the HCE register in order to disable the host controller.\r
   //\r
-  Address = Private->UfsHcBase + UFS_HC_ENABLE_OFFSET;\r
-  Data    = MmioRead32 (Address);\r
+  Status = UfsMmioRead32 (Private, UFS_HC_ENABLE_OFFSET, &Data);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
   ASSERT ((Data & UFS_HC_HCE_EN) == UFS_HC_HCE_EN);\r
-  MmioWrite32 (Address, 0);\r
+\r
+  Status = UfsMmioWrite32 (Private, UFS_HC_ENABLE_OFFSET, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Wait until HCE is read as '0' before continuing.\r
   //\r
-  Status = UfsWaitMemSet (Address, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);\r
+  Status = UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
index 83db1a7bbd0c9a8e70262d4a35e6c3c3180e809b..909c981729032ff76d8aefd967e88e42752831c2 100644 (file)
@@ -2,7 +2,7 @@
 \r
   EDKII Universal Flash Storage Host Controller Protocol.\r
 \r
-Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed and made available under \r
 the terms and conditions of the BSD License that accompanies this distribution.  \r
 The full text of the license may be found at\r
@@ -185,6 +185,42 @@ EFI_STATUS
   IN  EDKII_UFS_HOST_CONTROLLER_PROTOCOL   *This\r
   );\r
 \r
+typedef enum {\r
+  EfiUfsHcWidthUint8      = 0,\r
+  EfiUfsHcWidthUint16,\r
+  EfiUfsHcWidthUint32,\r
+  EfiUfsHcWidthUint64,\r
+  EfiUfsHcWidthMaximum\r
+} EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH;\r
+\r
+/**\r
+  Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.\r
+\r
+  @param  This                  A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.\r
+  @param  Width                 Signifies the width of the memory operations.\r
+  @param  Offset                The offset within the UFS Host Controller MMIO space to start the\r
+                                memory operation.\r
+  @param  Count                 The number of memory operations to perform.\r
+  @param  Buffer                For read operations, the destination buffer to store the results.\r
+                                For write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS           The data was read from or written to the UFS host controller.\r
+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not\r
+                                valid for the UFS Host Controller memory space.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EDKII_UFS_HC_MMIO_READ_WRITE)(\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This,\r
+  IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH  Width,\r
+  IN     UINT64                                    Offset,\r
+  IN     UINTN                                     Count,\r
+  IN OUT VOID                                      *Buffer\r
+  );\r
+\r
 ///\r
 ///  UFS Host Controller Protocol structure.\r
 ///\r
@@ -195,6 +231,8 @@ struct _EDKII_UFS_HOST_CONTROLLER_PROTOCOL {
   EDKII_UFS_HC_MAP                    Map;\r
   EDKII_UFS_HC_UNMAP                  Unmap;\r
   EDKII_UFS_HC_FLUSH                  Flush;\r
+  EDKII_UFS_HC_MMIO_READ_WRITE        Read;\r
+  EDKII_UFS_HC_MMIO_READ_WRITE        Write;\r
 };\r
 \r
 ///\r