]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
SecurityPkg/OpalPassword: Add PCD to skip password prompt
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPassword / OpalDriver.c
index 38268539fb055b9ddb51f693e3cfc144bf06cbf1..e14fa32354ea09c7665e661c95ba0dcbe48e7c63 100644 (file)
@@ -2,14 +2,8 @@
   Entrypoint of Opal UEFI Driver and contains all the logic to\r
   register for new Opal device instances.\r
 \r
   Entrypoint of Opal UEFI Driver and contains all the logic to\r
   register for new Opal device instances.\r
 \r
-Copyright (c) 2016 - 2018, 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
+Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
 **/\r
 \r
@@ -21,40 +15,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "OpalDriver.h"\r
 #include "OpalHii.h"\r
 \r
 #include "OpalDriver.h"\r
 #include "OpalHii.h"\r
 \r
-EFI_GUID mOpalDeviceAtaGuid = OPAL_DEVICE_ATA_GUID;\r
-EFI_GUID mOpalDeviceNvmeGuid = OPAL_DEVICE_NVME_GUID;\r
+EFI_GUID mOpalDeviceLockBoxGuid = OPAL_DEVICE_LOCKBOX_GUID;\r
 \r
 BOOLEAN                 mOpalEndOfDxe = FALSE;\r
 OPAL_REQUEST_VARIABLE   *mOpalRequestVariable = NULL;\r
 UINTN                   mOpalRequestVariableSize = 0;\r
 CHAR16                  mPopUpString[100];\r
 \r
 \r
 BOOLEAN                 mOpalEndOfDxe = FALSE;\r
 OPAL_REQUEST_VARIABLE   *mOpalRequestVariable = NULL;\r
 UINTN                   mOpalRequestVariableSize = 0;\r
 CHAR16                  mPopUpString[100];\r
 \r
-typedef struct {\r
-  UINT32                   Address;\r
-  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
-} OPAL_HC_PCI_REGISTER_SAVE;\r
-\r
-//\r
-// To unlock the Intel SATA controller at S3 Resume, restored the following registers.\r
-//\r
-const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate[] = {\r
-  {0x9,  S3BootScriptWidthUint8},\r
-  {0x10, S3BootScriptWidthUint32},\r
-  {0x14, S3BootScriptWidthUint32},\r
-  {0x18, S3BootScriptWidthUint32},\r
-  {0x1C, S3BootScriptWidthUint32},\r
-  {0x20, S3BootScriptWidthUint32},\r
-  {0x24, S3BootScriptWidthUint32},\r
-  {0x3c, S3BootScriptWidthUint8},\r
-  {0x3d, S3BootScriptWidthUint8},\r
-  {0x40, S3BootScriptWidthUint16},\r
-  {0x42, S3BootScriptWidthUint16},\r
-  {0x92, S3BootScriptWidthUint16},\r
-  {0x94, S3BootScriptWidthUint32},\r
-  {0x9C, S3BootScriptWidthUint32},\r
-  {0x4,  S3BootScriptWidthUint16},\r
-};\r
-\r
 OPAL_DRIVER mOpalDriver;\r
 \r
 //\r
 OPAL_DRIVER mOpalDriver;\r
 \r
 //\r
@@ -233,14 +200,12 @@ OpalSupportUpdatePassword (
   @param[out] DevInfoLength     Device information length needed.\r
   @param[out] DevInfo           Device information extracted.\r
 \r
   @param[out] DevInfoLength     Device information length needed.\r
   @param[out] DevInfo           Device information extracted.\r
 \r
-  @return Device type.\r
-\r
 **/\r
 **/\r
-UINT8\r
+VOID\r
 ExtractDeviceInfoFromDevicePath (\r
   IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
 ExtractDeviceInfoFromDevicePath (\r
   IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
-  OUT UINT16                    *DevInfoLength,\r
-  OUT OPAL_DEVICE_COMMON        *DevInfo OPTIONAL\r
+  OUT UINT32                    *DevInfoLength,\r
+  OUT OPAL_DEVICE_LOCKBOX_DATA  *DevInfo OPTIONAL\r
   )\r
 {\r
   EFI_DEVICE_PATH_PROTOCOL      *TmpDevPath;\r
   )\r
 {\r
   EFI_DEVICE_PATH_PROTOCOL      *TmpDevPath;\r
@@ -249,10 +214,6 @@ ExtractDeviceInfoFromDevicePath (
   UINT8                         DeviceType;\r
   UINT8                         BusNum;\r
   OPAL_PCI_DEVICE               *PciDevice;\r
   UINT8                         DeviceType;\r
   UINT8                         BusNum;\r
   OPAL_PCI_DEVICE               *PciDevice;\r
-  OPAL_DEVICE_ATA               *DevInfoAta;\r
-  OPAL_DEVICE_NVME              *DevInfoNvme;\r
-  SATA_DEVICE_PATH              *SataDevPath;\r
-  NVME_NAMESPACE_DEVICE_PATH    *NvmeDevPath;\r
 \r
   ASSERT (DevicePath != NULL);\r
   ASSERT (DevInfoLength != NULL);\r
 \r
   ASSERT (DevicePath != NULL);\r
   ASSERT (DevInfoLength != NULL);\r
@@ -266,30 +227,15 @@ ExtractDeviceInfoFromDevicePath (
   // Get device type.\r
   //\r
   while (!IsDevicePathEnd (TmpDevPath)) {\r
   // Get device type.\r
   //\r
   while (!IsDevicePathEnd (TmpDevPath)) {\r
-    if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_SATA_DP) {\r
-      //\r
-      // SATA\r
-      //\r
-      if (DevInfo != NULL) {\r
-        SataDevPath = (SATA_DEVICE_PATH *) TmpDevPath;\r
-        DevInfoAta = (OPAL_DEVICE_ATA *) DevInfo;\r
-        DevInfoAta->Port = SataDevPath->HBAPortNumber;\r
-        DevInfoAta->PortMultiplierPort = SataDevPath->PortMultiplierPortNumber;\r
-      }\r
-      DeviceType = OPAL_DEVICE_TYPE_ATA;\r
-      *DevInfoLength = sizeof (OPAL_DEVICE_ATA);\r
-      break;\r
-    } else if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP) {\r
-      //\r
-      // NVMe\r
-      //\r
+    if ((TmpDevPath->Type == MESSAGING_DEVICE_PATH) &&\r
+        (TmpDevPath->SubType == MSG_SATA_DP || TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP)) {\r
       if (DevInfo != NULL) {\r
       if (DevInfo != NULL) {\r
-        NvmeDevPath = (NVME_NAMESPACE_DEVICE_PATH *) TmpDevPath;\r
-        DevInfoNvme = (OPAL_DEVICE_NVME *) DevInfo;\r
-        DevInfoNvme->NvmeNamespaceId = NvmeDevPath->NamespaceId;\r
+        DevInfo->DevicePathLength = (UINT32) GetDevicePathSize (DevicePath);\r
+        CopyMem (DevInfo->DevicePath, DevicePath, DevInfo->DevicePathLength);\r
       }\r
       }\r
-      DeviceType = OPAL_DEVICE_TYPE_NVME;\r
-      *DevInfoLength = sizeof (OPAL_DEVICE_NVME);\r
+\r
+      DeviceType = (TmpDevPath->SubType == MSG_SATA_DP) ? OPAL_DEVICE_TYPE_ATA : OPAL_DEVICE_TYPE_NVME;\r
+      *DevInfoLength = sizeof (OPAL_DEVICE_LOCKBOX_DATA) + (UINT32) GetDevicePathSize (DevicePath);\r
       break;\r
     }\r
     TmpDevPath = NextDevicePathNode (TmpDevPath);\r
       break;\r
     }\r
     TmpDevPath = NextDevicePathNode (TmpDevPath);\r
@@ -304,8 +250,8 @@ ExtractDeviceInfoFromDevicePath (
   while (!IsDevicePathEnd (TmpDevPath2)) {\r
     if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath->SubType == HW_PCI_DP) {\r
       PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath;\r
   while (!IsDevicePathEnd (TmpDevPath2)) {\r
     if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath->SubType == HW_PCI_DP) {\r
       PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath;\r
-      if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)||\r
-          (TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_SATA_DP)) {\r
+      if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH) &&\r
+          (TmpDevPath2->SubType == MSG_SATA_DP || TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)) {\r
         if (DevInfo != NULL) {\r
           PciDevice = &DevInfo->Device;\r
           PciDevice->Segment = 0;\r
         if (DevInfo != NULL) {\r
           PciDevice = &DevInfo->Device;\r
           PciDevice->Segment = 0;\r
@@ -314,14 +260,6 @@ ExtractDeviceInfoFromDevicePath (
           PciDevice->Function = PciDevPath->Function;\r
         }\r
       } else {\r
           PciDevice->Function = PciDevPath->Function;\r
         }\r
       } else {\r
-        if (DevInfo != NULL) {\r
-          PciDevice = (OPAL_PCI_DEVICE *) ((UINTN) DevInfo + *DevInfoLength);\r
-          PciDevice->Segment = 0;\r
-          PciDevice->Bus = BusNum;\r
-          PciDevice->Device = PciDevPath->Device;\r
-          PciDevice->Function = PciDevPath->Function;\r
-        }\r
-        *DevInfoLength += sizeof (OPAL_PCI_DEVICE);\r
         if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH && TmpDevPath2->SubType == HW_PCI_DP) {\r
           BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));\r
         }\r
         if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH && TmpDevPath2->SubType == HW_PCI_DP) {\r
           BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));\r
         }\r
@@ -333,245 +271,203 @@ ExtractDeviceInfoFromDevicePath (
   }\r
 \r
   ASSERT (DeviceType != OPAL_DEVICE_TYPE_UNKNOWN);\r
   }\r
 \r
   ASSERT (DeviceType != OPAL_DEVICE_TYPE_UNKNOWN);\r
-  return DeviceType;\r
-}\r
-\r
-/**\r
-  Save boot script for ATA OPAL device.\r
-\r
-  @param[in] DevInfo    Pointer to ATA Opal device information.\r
-\r
- **/\r
-VOID\r
-OpalDeviceAtaSaveBootScript (\r
-  IN OPAL_DEVICE_ATA    *DevInfo\r
-  )\r
-{\r
-  UINTN                         Bus;\r
-  UINTN                         Device;\r
-  UINTN                         Function;\r
-  UINTN                         Index;\r
-  EFI_STATUS                    Status;\r
-  UINTN                         Offset;\r
-  UINT64                        Address;\r
-  S3_BOOT_SCRIPT_LIB_WIDTH      Width;\r
-  UINT32                        Data;\r
-  OPAL_HC_PCI_REGISTER_SAVE     *HcRegisterSaveListPtr;\r
-  UINTN                         Count;\r
-\r
-  Data = 0;\r
-\r
-  Bus        = DevInfo->Device.Bus;\r
-  Device     = DevInfo->Device.Device;\r
-  Function   = DevInfo->Device.Function;\r
-\r
-  HcRegisterSaveListPtr = (OPAL_HC_PCI_REGISTER_SAVE *) mSataHcRegisterSaveTemplate;\r
-  Count = sizeof (mSataHcRegisterSaveTemplate) / sizeof (OPAL_HC_PCI_REGISTER_SAVE);\r
-\r
-  for (Index = 0; Index < Count; Index++) {\r
-    Offset  = HcRegisterSaveListPtr[Index].Address;\r
-    Width   = HcRegisterSaveListPtr[Index].Width;\r
-\r
-    switch (Width) {\r
-      case S3BootScriptWidthUint8:\r
-        Data = (UINT32)PciRead8 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
-        break;\r
-      case S3BootScriptWidthUint16:\r
-        Data = (UINT32)PciRead16 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
-        break;\r
-      case S3BootScriptWidthUint32:\r
-        Data = PciRead32 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
-        break;\r
-      default:\r
-        ASSERT (FALSE);\r
-        break;\r
-    }\r
-\r
-    Address = S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus, Device, Function, Offset);\r
-    Status  = S3BootScriptSavePciCfgWrite (Width, Address, 1, &Data);\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
+  return;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Build ATA OPAL device info and save them to LockBox.\r
-\r
-  @param[in] BarAddr    Bar address allocated.\r
+  Build OPAL device info and save them to LockBox.\r
 \r
  **/\r
 VOID\r
 \r
  **/\r
 VOID\r
-BuildOpalDeviceInfoAta (\r
-  IN UINT32     BarAddr\r
+BuildOpalDeviceInfo (\r
+  VOID\r
   )\r
 {\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  UINT8                 DeviceType;\r
-  OPAL_DEVICE_ATA       *DevInfoAta;\r
-  OPAL_DEVICE_ATA       *TempDevInfoAta;\r
-  UINTN                 DevInfoLengthAta;\r
-  UINT16                DevInfoLength;\r
-  OPAL_DRIVER_DEVICE    *TmpDev;\r
+  EFI_STATUS                  Status;\r
+  OPAL_DEVICE_LOCKBOX_DATA    *DevInfo;\r
+  OPAL_DEVICE_LOCKBOX_DATA    *TempDevInfo;\r
+  UINTN                       TotalDevInfoLength;\r
+  UINT32                      DevInfoLength;\r
+  OPAL_DRIVER_DEVICE          *TmpDev;\r
+  UINT8                       DummyData;\r
+  BOOLEAN                     S3InitDevicesExist;\r
+  UINTN                       S3InitDevicesLength;\r
+  EFI_DEVICE_PATH_PROTOCOL    *S3InitDevices;\r
+  EFI_DEVICE_PATH_PROTOCOL    *S3InitDevicesBak;\r
 \r
   //\r
 \r
   //\r
-  // Build ATA OPAL device info and save them to LockBox.\r
+  // Build OPAL device info and save them to LockBox.\r
   //\r
   //\r
-  DevInfoLengthAta = 0;\r
+  TotalDevInfoLength = 0;\r
   TmpDev = mOpalDriver.DeviceList;\r
   while (TmpDev != NULL) {\r
   TmpDev = mOpalDriver.DeviceList;\r
   while (TmpDev != NULL) {\r
-    DeviceType = ExtractDeviceInfoFromDevicePath (\r
-                   TmpDev->OpalDisk.OpalDevicePath,\r
-                   &DevInfoLength,\r
-                   NULL\r
-                   );\r
-    if (DeviceType == OPAL_DEVICE_TYPE_ATA) {\r
-      DevInfoLengthAta += DevInfoLength;\r
-    }\r
-\r
+    ExtractDeviceInfoFromDevicePath (\r
+      TmpDev->OpalDisk.OpalDevicePath,\r
+      &DevInfoLength,\r
+      NULL\r
+      );\r
+    TotalDevInfoLength += DevInfoLength;\r
     TmpDev = TmpDev->Next;\r
   }\r
 \r
     TmpDev = TmpDev->Next;\r
   }\r
 \r
-  if (DevInfoLengthAta == 0) {\r
+  if (TotalDevInfoLength == 0) {\r
     return;\r
   }\r
 \r
     return;\r
   }\r
 \r
-  DevInfoAta = AllocateZeroPool (DevInfoLengthAta);\r
-  ASSERT (DevInfoAta != NULL);\r
+  S3InitDevicesLength = sizeof (DummyData);\r
+  Status = RestoreLockBox (\r
+             &gS3StorageDeviceInitListGuid,\r
+             &DummyData,\r
+             &S3InitDevicesLength\r
+             );\r
+  ASSERT ((Status == EFI_NOT_FOUND) || (Status == EFI_BUFFER_TOO_SMALL));\r
+  if (Status == EFI_NOT_FOUND) {\r
+    S3InitDevices      = NULL;\r
+    S3InitDevicesExist = FALSE;\r
+  } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    S3InitDevices = AllocatePool (S3InitDevicesLength);\r
+    ASSERT (S3InitDevices != NULL);\r
+    if (S3InitDevices == NULL) {\r
+      return;\r
+    }\r
 \r
 \r
-  TempDevInfoAta = DevInfoAta;\r
-  TmpDev = mOpalDriver.DeviceList;\r
+    Status = RestoreLockBox (\r
+               &gS3StorageDeviceInitListGuid,\r
+               S3InitDevices,\r
+               &S3InitDevicesLength\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+    S3InitDevicesExist = TRUE;\r
+  } else {\r
+    return;\r
+  }\r
+\r
+  DevInfo = AllocateZeroPool (TotalDevInfoLength);\r
+  ASSERT (DevInfo != NULL);\r
+  if (DevInfo == NULL) {\r
+    return;\r
+  }\r
+\r
+  TempDevInfo = DevInfo;\r
+  TmpDev      = mOpalDriver.DeviceList;\r
   while (TmpDev != NULL) {\r
   while (TmpDev != NULL) {\r
-    DeviceType = ExtractDeviceInfoFromDevicePath (\r
-                   TmpDev->OpalDisk.OpalDevicePath,\r
-                   &DevInfoLength,\r
-                   NULL\r
-                   );\r
-    if (DeviceType == OPAL_DEVICE_TYPE_ATA) {\r
-      ExtractDeviceInfoFromDevicePath (\r
-        TmpDev->OpalDisk.OpalDevicePath,\r
-        &DevInfoLength,\r
-        (OPAL_DEVICE_COMMON *) TempDevInfoAta\r
-        );\r
-      TempDevInfoAta->Length = DevInfoLength;\r
-      TempDevInfoAta->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId;\r
-      TempDevInfoAta->BarAddr = BarAddr;\r
-      CopyMem (\r
-        TempDevInfoAta->Password,\r
-        TmpDev->OpalDisk.Password,\r
-        TmpDev->OpalDisk.PasswordLength\r
-        );\r
-      TempDevInfoAta->PasswordLength = TmpDev->OpalDisk.PasswordLength;\r
-      OpalDeviceAtaSaveBootScript (TempDevInfoAta);\r
-      TempDevInfoAta = (OPAL_DEVICE_ATA *) ((UINTN) TempDevInfoAta + DevInfoLength);\r
+    ExtractDeviceInfoFromDevicePath (\r
+      TmpDev->OpalDisk.OpalDevicePath,\r
+      &DevInfoLength,\r
+      TempDevInfo\r
+      );\r
+    TempDevInfo->Length = DevInfoLength;\r
+    TempDevInfo->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId;\r
+    CopyMem (\r
+      TempDevInfo->Password,\r
+      TmpDev->OpalDisk.Password,\r
+      TmpDev->OpalDisk.PasswordLength\r
+      );\r
+    TempDevInfo->PasswordLength = TmpDev->OpalDisk.PasswordLength;\r
+\r
+    S3InitDevicesBak = S3InitDevices;\r
+    S3InitDevices    = AppendDevicePathInstance (\r
+                         S3InitDevicesBak,\r
+                         TmpDev->OpalDisk.OpalDevicePath\r
+                         );\r
+    if (S3InitDevicesBak != NULL) {\r
+      FreePool (S3InitDevicesBak);\r
+    }\r
+    ASSERT (S3InitDevices != NULL);\r
+    if (S3InitDevices == NULL) {\r
+      return;\r
     }\r
 \r
     }\r
 \r
+    TempDevInfo = (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN) TempDevInfo + DevInfoLength);\r
     TmpDev = TmpDev->Next;\r
   }\r
 \r
   Status = SaveLockBox (\r
     TmpDev = TmpDev->Next;\r
   }\r
 \r
   Status = SaveLockBox (\r
-             &mOpalDeviceAtaGuid,\r
-             DevInfoAta,\r
-             DevInfoLengthAta\r
+             &mOpalDeviceLockBoxGuid,\r
+             DevInfo,\r
+             TotalDevInfoLength\r
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   Status = SetLockBoxAttributes (\r
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   Status = SetLockBoxAttributes (\r
-             &mOpalDeviceAtaGuid,\r
+             &mOpalDeviceLockBoxGuid,\r
              LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\r
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
              LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\r
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  ZeroMem (DevInfoAta, DevInfoLengthAta);\r
-  FreePool (DevInfoAta);\r
+  S3InitDevicesLength = GetDevicePathSize (S3InitDevices);\r
+  if (S3InitDevicesExist) {\r
+    Status = UpdateLockBox (\r
+               &gS3StorageDeviceInitListGuid,\r
+               0,\r
+               S3InitDevices,\r
+               S3InitDevicesLength\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+  } else {\r
+    Status = SaveLockBox (\r
+               &gS3StorageDeviceInitListGuid,\r
+               S3InitDevices,\r
+               S3InitDevicesLength\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Status = SetLockBoxAttributes (\r
+               &gS3StorageDeviceInitListGuid,\r
+               LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  ZeroMem (DevInfo, TotalDevInfoLength);\r
+  FreePool (DevInfo);\r
+  FreePool (S3InitDevices);\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Build NVMe OPAL device info and save them to LockBox.\r
 \r
 \r
-  @param[in] BarAddr    Bar address allocated.\r
+  Send BlockSid command if needed.\r
 \r
 \r
- **/\r
+**/\r
 VOID\r
 VOID\r
-BuildOpalDeviceInfoNvme (\r
-  IN UINT32     BarAddr\r
+SendBlockSidCommand (\r
+  VOID\r
   )\r
 {\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  UINT8                 DeviceType;\r
-  OPAL_DEVICE_NVME      *DevInfoNvme;\r
-  OPAL_DEVICE_NVME      *TempDevInfoNvme;\r
-  UINTN                 DevInfoLengthNvme;\r
-  UINT16                DevInfoLength;\r
-  OPAL_DRIVER_DEVICE    *TmpDev;\r
-\r
-  //\r
-  // Build NVMe OPAL device info and save them to LockBox.\r
-  //\r
-  DevInfoLengthNvme = 0;\r
-  TmpDev = mOpalDriver.DeviceList;\r
-  while (TmpDev != NULL) {\r
-    DeviceType = ExtractDeviceInfoFromDevicePath (\r
-                   TmpDev->OpalDisk.OpalDevicePath,\r
-                   &DevInfoLength,\r
-                   NULL\r
-                   );\r
-    if (DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
-      DevInfoLengthNvme += DevInfoLength;\r
-    }\r
+  OPAL_DRIVER_DEVICE                         *Itr;\r
+  TCG_RESULT                                 Result;\r
+  OPAL_SESSION                               Session;\r
+  UINT32                                     PpStorageFlag;\r
 \r
 \r
-    TmpDev = TmpDev->Next;\r
-  }\r
+  PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();\r
+  if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {\r
+    //\r
+    // Send BlockSID command to each Opal disk\r
+    //\r
+    Itr = mOpalDriver.DeviceList;\r
+    while (Itr != NULL) {\r
+      if (Itr->OpalDisk.SupportedAttributes.BlockSid) {\r
+        ZeroMem(&Session, sizeof(Session));\r
+        Session.Sscp = Itr->OpalDisk.Sscp;\r
+        Session.MediaId = Itr->OpalDisk.MediaId;\r
+        Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;\r
 \r
 \r
-  if (DevInfoLengthNvme == 0) {\r
-    return;\r
-  }\r
+        DEBUG ((DEBUG_INFO, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n"));\r
+        Result = OpalBlockSid (&Session, TRUE);  // HardwareReset must always be TRUE\r
+        if (Result != TcgResultSuccess) {\r
+          DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));\r
+          break;\r
+        }\r
 \r
 \r
-  DevInfoNvme = AllocateZeroPool (DevInfoLengthNvme);\r
-  ASSERT (DevInfoNvme != NULL);\r
+        //\r
+        // Record BlockSID command has been sent.\r
+        //\r
+        Itr->OpalDisk.SentBlockSID = TRUE;\r
+      }\r
 \r
 \r
-  TempDevInfoNvme = DevInfoNvme;\r
-  TmpDev = mOpalDriver.DeviceList;\r
-  while (TmpDev != NULL) {\r
-    DeviceType = ExtractDeviceInfoFromDevicePath (\r
-                   TmpDev->OpalDisk.OpalDevicePath,\r
-                   &DevInfoLength,\r
-                   NULL\r
-                   );\r
-    if (DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
-      ExtractDeviceInfoFromDevicePath (\r
-        TmpDev->OpalDisk.OpalDevicePath,\r
-        &DevInfoLength,\r
-        (OPAL_DEVICE_COMMON *) TempDevInfoNvme\r
-        );\r
-      TempDevInfoNvme->Length = DevInfoLength;\r
-      TempDevInfoNvme->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId;\r
-      TempDevInfoNvme->BarAddr = BarAddr;\r
-      CopyMem (\r
-        TempDevInfoNvme->Password,\r
-        TmpDev->OpalDisk.Password,\r
-        TmpDev->OpalDisk.PasswordLength\r
-        );\r
-      TempDevInfoNvme->PasswordLength = TmpDev->OpalDisk.PasswordLength;\r
-      TempDevInfoNvme = (OPAL_DEVICE_NVME *) ((UINTN) TempDevInfoNvme + DevInfoLength);\r
+      Itr = Itr->Next;\r
     }\r
     }\r
-\r
-    TmpDev = TmpDev->Next;\r
   }\r
   }\r
-\r
-  Status = SaveLockBox (\r
-             &mOpalDeviceNvmeGuid,\r
-             DevInfoNvme,\r
-             DevInfoLengthNvme\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = SetLockBoxAttributes (\r
-             &mOpalDeviceNvmeGuid,\r
-             LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  ZeroMem (DevInfoNvme, DevInfoLengthNvme);\r
-  FreePool (DevInfoNvme);\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -590,9 +486,6 @@ OpalEndOfDxeEventNotify (
   VOID                                    *Context\r
   )\r
 {\r
   VOID                                    *Context\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  EFI_PHYSICAL_ADDRESS  Address;\r
-  UINT64                Length;\r
   OPAL_DRIVER_DEVICE    *TmpDev;\r
 \r
   DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));\r
   OPAL_DRIVER_DEVICE    *TmpDev;\r
 \r
   DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));\r
@@ -617,24 +510,7 @@ OpalEndOfDxeEventNotify (
     return;\r
   }\r
 \r
     return;\r
   }\r
 \r
-  //\r
-  // Assume 64K size and alignment are enough.\r
-  //\r
-  Length = 0x10000;\r
-  Address = 0xFFFFFFFF;\r
-  Status = gDS->AllocateMemorySpace (\r
-                  EfiGcdAllocateMaxAddressSearchBottomUp,\r
-                  EfiGcdMemoryTypeMemoryMappedIo,\r
-                  16,                             // 2^16: 64K Alignment\r
-                  Length,\r
-                  &Address,\r
-                  gImageHandle,\r
-                  NULL\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  BuildOpalDeviceInfoAta ((UINT32) Address);\r
-  BuildOpalDeviceInfoNvme ((UINT32) Address);\r
+  BuildOpalDeviceInfo ();\r
 \r
   //\r
   // Zero passsword.\r
 \r
   //\r
   // Zero passsword.\r
@@ -645,6 +521,11 @@ OpalEndOfDxeEventNotify (
     TmpDev = TmpDev->Next;\r
   }\r
 \r
     TmpDev = TmpDev->Next;\r
   }\r
 \r
+  //\r
+  // Send BlockSid command if needed.\r
+  //\r
+  SendBlockSidCommand ();\r
+\r
   DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));\r
 \r
   gBS->CloseEvent (Event);\r
   DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));\r
 \r
   gBS->CloseEvent (Event);\r
@@ -657,6 +538,7 @@ OpalEndOfDxeEventNotify (
                             OPAL request.\r
   @param[in]  PopUpString   Pop up string.\r
   @param[in]  PopUpString2  Pop up string in line 2.\r
                             OPAL request.\r
   @param[in]  PopUpString   Pop up string.\r
   @param[in]  PopUpString2  Pop up string in line 2.\r
+  @param[in]  PopUpString3  Pop up string in line 3.\r
 \r
   @param[out] PressEsc      Whether user escape function through Press ESC.\r
 \r
 \r
   @param[out] PressEsc      Whether user escape function through Press ESC.\r
 \r
@@ -668,6 +550,7 @@ OpalDriverPopUpPsidInput (
   IN OPAL_DRIVER_DEVICE     *Dev,\r
   IN CHAR16                 *PopUpString,\r
   IN CHAR16                 *PopUpString2,\r
   IN OPAL_DRIVER_DEVICE     *Dev,\r
   IN CHAR16                 *PopUpString,\r
   IN CHAR16                 *PopUpString2,\r
+  IN CHAR16                 *PopUpString3,\r
   OUT BOOLEAN               *PressEsc\r
   )\r
 {\r
   OUT BOOLEAN               *PressEsc\r
   )\r
 {\r
@@ -697,15 +580,28 @@ OpalDriverPopUpPsidInput (
         NULL\r
       );\r
     } else {\r
         NULL\r
       );\r
     } else {\r
-      CreatePopUp (\r
-        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-        &InputKey,\r
-        PopUpString,\r
-        PopUpString2,\r
-        L"---------------------",\r
-        Mask,\r
-        NULL\r
-      );\r
+      if (PopUpString3 == NULL) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &InputKey,\r
+          PopUpString,\r
+          PopUpString2,\r
+          L"---------------------",\r
+          Mask,\r
+          NULL\r
+        );\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &InputKey,\r
+          PopUpString,\r
+          PopUpString2,\r
+          PopUpString3,\r
+          L"---------------------",\r
+          Mask,\r
+          NULL\r
+        );\r
+      }\r
     }\r
 \r
     //\r
     }\r
 \r
     //\r
@@ -795,6 +691,7 @@ OpalDriverPopUpPsidInput (
                             process OPAL request.\r
   @param[in]  PopUpString1  Pop up string 1.\r
   @param[in]  PopUpString2  Pop up string 2.\r
                             process OPAL request.\r
   @param[in]  PopUpString1  Pop up string 1.\r
   @param[in]  PopUpString2  Pop up string 2.\r
+  @param[in]  PopUpString3  Pop up string 3.\r
   @param[out] PressEsc      Whether user escape function through Press ESC.\r
 \r
   @retval Password string if success. NULL if failed.\r
   @param[out] PressEsc      Whether user escape function through Press ESC.\r
 \r
   @retval Password string if success. NULL if failed.\r
@@ -805,6 +702,7 @@ OpalDriverPopUpPasswordInput (
   IN OPAL_DRIVER_DEVICE     *Dev,\r
   IN CHAR16                 *PopUpString1,\r
   IN CHAR16                 *PopUpString2,\r
   IN OPAL_DRIVER_DEVICE     *Dev,\r
   IN CHAR16                 *PopUpString1,\r
   IN CHAR16                 *PopUpString2,\r
+  IN CHAR16                 *PopUpString3,\r
   OUT BOOLEAN               *PressEsc\r
   )\r
 {\r
   OUT BOOLEAN               *PressEsc\r
   )\r
 {\r
@@ -834,15 +732,28 @@ OpalDriverPopUpPasswordInput (
         NULL\r
       );\r
     } else {\r
         NULL\r
       );\r
     } else {\r
-      CreatePopUp (\r
-        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-        &InputKey,\r
-        PopUpString1,\r
-        PopUpString2,\r
-        L"---------------------",\r
-        Mask,\r
-        NULL\r
-      );\r
+      if (PopUpString3 == NULL) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &InputKey,\r
+          PopUpString1,\r
+          PopUpString2,\r
+          L"---------------------",\r
+          Mask,\r
+          NULL\r
+        );\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &InputKey,\r
+          PopUpString1,\r
+          PopUpString2,\r
+          PopUpString3,\r
+          L"---------------------",\r
+          Mask,\r
+          NULL\r
+        );\r
+      }\r
     }\r
 \r
     //\r
     }\r
 \r
     //\r
@@ -988,8 +899,24 @@ OpalDriverRequestPassword (
 \r
     IsLocked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
 \r
 \r
     IsLocked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
 \r
+    //\r
+    // Add PcdSkipOpalPasswordPrompt to determin whether to skip password prompt.\r
+    // Due to board design, device may not power off during system warm boot, which result in\r
+    // security status remain unlocked status, hence we add device security status check here.\r
+    //\r
+    // If device is in the locked status, device keeps locked and system continues booting.\r
+    // If device is in the unlocked status, system is forced shutdown to support security requirement.\r
+    //\r
+    if (PcdGetBool (PcdSkipOpalPasswordPrompt)) {\r
+      if (IsLocked) {\r
+        return;\r
+      } else {\r
+        gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
+      }\r
+    }\r
+\r
     while (Count < MAX_PASSWORD_TRY_COUNT) {\r
     while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-      Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc);\r
+      Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
       if (PressEsc) {\r
         if (IsLocked) {\r
           //\r
       if (PressEsc) {\r
         if (IsLocked) {\r
           //\r
@@ -1154,7 +1081,7 @@ ProcessOpalRequestEnableFeature (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1183,7 +1110,7 @@ ProcessOpalRequestEnableFeature (
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
-    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc);\r
+    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (Password, PasswordLen);\r
       FreePool (Password);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (Password, PasswordLen);\r
       FreePool (Password);\r
@@ -1298,7 +1225,7 @@ ProcessOpalRequestDisableUser (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1393,6 +1320,7 @@ ProcessOpalRequestPsidRevert (
   TCG_RESULT            Ret;\r
   CHAR16                *PopUpString;\r
   CHAR16                *PopUpString2;\r
   TCG_RESULT            Ret;\r
   CHAR16                *PopUpString;\r
   CHAR16                *PopUpString2;\r
+  CHAR16                *PopUpString3;\r
   UINTN                 BufferSize;\r
 \r
   if (Dev == NULL) {\r
   UINTN                 BufferSize;\r
 \r
   if (Dev == NULL) {\r
@@ -1404,17 +1332,19 @@ ProcessOpalRequestPsidRevert (
   PopUpString = OpalGetPopUpString (Dev, RequestString);\r
 \r
   if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
   PopUpString = OpalGetPopUpString (Dev, RequestString);\r
 \r
   if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
-    BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");\r
+    BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
     PopUpString2 = AllocateZeroPool (BufferSize);\r
     ASSERT (PopUpString2 != NULL);\r
     UnicodeSPrint (\r
         PopUpString2,\r
         BufferSize,\r
     PopUpString2 = AllocateZeroPool (BufferSize);\r
     ASSERT (PopUpString2 != NULL);\r
     UnicodeSPrint (\r
         PopUpString2,\r
         BufferSize,\r
-        L"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",\r
+        L"WARNING: Revert action will take about %d seconds",\r
         Dev->OpalDisk.EstimateTimeCost\r
       );\r
         Dev->OpalDisk.EstimateTimeCost\r
       );\r
+    PopUpString3 = L"DO NOT power off system during the revert action!";\r
   } else {\r
     PopUpString2 = NULL;\r
   } else {\r
     PopUpString2 = NULL;\r
+    PopUpString3 = NULL;\r
   }\r
 \r
   Count = 0;\r
   }\r
 \r
   Count = 0;\r
@@ -1425,7 +1355,7 @@ ProcessOpalRequestPsidRevert (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PSID_TRY_COUNT) {\r
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PSID_TRY_COUNT) {\r
-    Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, &PressEsc);\r
+    Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1527,6 +1457,7 @@ ProcessOpalRequestRevert (
   BOOLEAN               PasswordFailed;\r
   CHAR16                *PopUpString;\r
   CHAR16                *PopUpString2;\r
   BOOLEAN               PasswordFailed;\r
   CHAR16                *PopUpString;\r
   CHAR16                *PopUpString2;\r
+  CHAR16                *PopUpString3;\r
   UINTN                 BufferSize;\r
 \r
   if (Dev == NULL) {\r
   UINTN                 BufferSize;\r
 \r
   if (Dev == NULL) {\r
@@ -1539,17 +1470,19 @@ ProcessOpalRequestRevert (
 \r
   if ((!KeepUserData) &&\r
       (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME)) {\r
 \r
   if ((!KeepUserData) &&\r
       (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME)) {\r
-    BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");\r
+    BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
     PopUpString2 = AllocateZeroPool (BufferSize);\r
     ASSERT (PopUpString2 != NULL);\r
     UnicodeSPrint (\r
         PopUpString2,\r
         BufferSize,\r
     PopUpString2 = AllocateZeroPool (BufferSize);\r
     ASSERT (PopUpString2 != NULL);\r
     UnicodeSPrint (\r
         PopUpString2,\r
         BufferSize,\r
-        L"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",\r
+        L"WARNING: Revert action will take about %d seconds",\r
         Dev->OpalDisk.EstimateTimeCost\r
       );\r
         Dev->OpalDisk.EstimateTimeCost\r
       );\r
+    PopUpString3 = L"DO NOT power off system during the revert action!";\r
   } else {\r
     PopUpString2 = NULL;\r
   } else {\r
     PopUpString2 = NULL;\r
+    PopUpString3 = NULL;\r
   }\r
 \r
   Count = 0;\r
   }\r
 \r
   Count = 0;\r
@@ -1560,7 +1493,7 @@ ProcessOpalRequestRevert (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1686,6 +1619,9 @@ ProcessOpalRequestSecureErase (
   TCG_RESULT            Ret;\r
   BOOLEAN               PasswordFailed;\r
   CHAR16                *PopUpString;\r
   TCG_RESULT            Ret;\r
   BOOLEAN               PasswordFailed;\r
   CHAR16                *PopUpString;\r
+  CHAR16                *PopUpString2;\r
+  CHAR16                *PopUpString3;\r
+  UINTN                 BufferSize;\r
 \r
   if (Dev == NULL) {\r
     return;\r
 \r
   if (Dev == NULL) {\r
     return;\r
@@ -1695,6 +1631,21 @@ ProcessOpalRequestSecureErase (
 \r
   PopUpString = OpalGetPopUpString (Dev, RequestString);\r
 \r
 \r
   PopUpString = OpalGetPopUpString (Dev, RequestString);\r
 \r
+  if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
+    BufferSize = StrSize (L"Warning: Secure erase action will take about ####### seconds");\r
+    PopUpString2 = AllocateZeroPool (BufferSize);\r
+    ASSERT (PopUpString2 != NULL);\r
+    UnicodeSPrint (\r
+        PopUpString2,\r
+        BufferSize,\r
+        L"WARNING: Secure erase action will take about %d seconds",\r
+        Dev->OpalDisk.EstimateTimeCost\r
+      );\r
+    PopUpString3 = L"DO NOT power off system during the action!";\r
+  } else {\r
+    PopUpString2 = NULL;\r
+    PopUpString3 = NULL;\r
+  }\r
   Count = 0;\r
 \r
   ZeroMem(&Session, sizeof(Session));\r
   Count = 0;\r
 \r
   ZeroMem(&Session, sizeof(Session));\r
@@ -1703,7 +1654,7 @@ ProcessOpalRequestSecureErase (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1717,7 +1668,7 @@ ProcessOpalRequestSecureErase (
 \r
         if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
           gST->ConOut->ClearScreen(gST->ConOut);\r
 \r
         if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
           gST->ConOut->ClearScreen(gST->ConOut);\r
-          return;\r
+          goto Done;\r
         } else {\r
           //\r
           // Let user input password again.\r
         } else {\r
           //\r
           // Let user input password again.\r
@@ -1774,6 +1725,11 @@ ProcessOpalRequestSecureErase (
     } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
     gST->ConOut->ClearScreen(gST->ConOut);\r
   }\r
     } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
     gST->ConOut->ClearScreen(gST->ConOut);\r
   }\r
+\r
+Done:\r
+  if (PopUpString2 != NULL) {\r
+    FreePool (PopUpString2);\r
+  }\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -1813,7 +1769,7 @@ ProcessOpalRequestSetUserPwd (
   Count = 0;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
   Count = 0;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", &PressEsc);\r
+    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1871,7 +1827,7 @@ ProcessOpalRequestSetUserPwd (
       }\r
     }\r
 \r
       }\r
     }\r
 \r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
     if (Password == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
     if (Password == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
@@ -1880,7 +1836,7 @@ ProcessOpalRequestSetUserPwd (
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
-    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc);\r
+    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
@@ -2012,7 +1968,7 @@ ProcessOpalRequestSetAdminPwd (
   Count = 0;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
   Count = 0;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", &PressEsc);\r
+    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -2065,7 +2021,7 @@ ProcessOpalRequestSetAdminPwd (
       continue;\r
     }\r
 \r
       continue;\r
     }\r
 \r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
     if (Password == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
     if (Password == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
@@ -2074,7 +2030,7 @@ ProcessOpalRequestSetAdminPwd (
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
-    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc);\r
+    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
@@ -2265,6 +2221,12 @@ ProcessOpalRequest (
         ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:");\r
       }\r
 \r
         ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:");\r
       }\r
 \r
+      //\r
+      // Update Device ownership.\r
+      // Later BlockSID command may block the update.\r
+      //\r
+      OpalDiskUpdateOwnerShip (&Dev->OpalDisk);\r
+\r
       break;\r
     }\r
 \r
       break;\r
     }\r
 \r
@@ -2369,53 +2331,6 @@ OpalDriverGetDeviceList(
   return mOpalDriver.DeviceList;\r
 }\r
 \r
   return mOpalDriver.DeviceList;\r
 }\r
 \r
-/**\r
-  ReadyToBoot callback to send BlockSid command.\r
-\r
-  @param  Event   Pointer to this event\r
-  @param  Context Event handler private Data\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ReadyToBootCallback (\r
-  IN EFI_EVENT        Event,\r
-  IN VOID             *Context\r
-  )\r
-{\r
-  OPAL_DRIVER_DEVICE                         *Itr;\r
-  TCG_RESULT                                 Result;\r
-  OPAL_SESSION                               Session;\r
-  UINT32                                     PpStorageFlag;\r
-\r
-  gBS->CloseEvent (Event);\r
-\r
-  PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();\r
-  if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {\r
-    //\r
-    // Send BlockSID command to each Opal disk\r
-    //\r
-    Itr = mOpalDriver.DeviceList;\r
-    while (Itr != NULL) {\r
-      if (Itr->OpalDisk.SupportedAttributes.BlockSid) {\r
-        ZeroMem(&Session, sizeof(Session));\r
-        Session.Sscp = Itr->OpalDisk.Sscp;\r
-        Session.MediaId = Itr->OpalDisk.MediaId;\r
-        Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;\r
-\r
-        DEBUG ((DEBUG_INFO, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));\r
-        Result = OpalBlockSid (&Session, TRUE);  // HardwareReset must always be TRUE\r
-        if (Result != TcgResultSuccess) {\r
-          DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));\r
-          break;\r
-        }\r
-      }\r
-\r
-      Itr = Itr->Next;\r
-    }\r
-  }\r
-}\r
-\r
 /**\r
   Stop this Controller.\r
 \r
 /**\r
   Stop this Controller.\r
 \r
@@ -2678,7 +2593,6 @@ EfiDriverEntryPoint(
   )\r
 {\r
   EFI_STATUS                     Status;\r
   )\r
 {\r
   EFI_STATUS                     Status;\r
-  EFI_EVENT                      ReadyToBootEvent;\r
   EFI_EVENT                      EndOfDxeEvent;\r
 \r
   Status = EfiLibInstallDriverBindingComponentName2 (\r
   EFI_EVENT                      EndOfDxeEvent;\r
 \r
   Status = EfiLibInstallDriverBindingComponentName2 (\r
@@ -2711,16 +2625,6 @@ EfiDriverEntryPoint(
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // register a ReadyToBoot event callback for sending BlockSid command\r
-  //\r
-  Status = EfiCreateEventReadyToBootEx (\r
-                  TPL_CALLBACK,\r
-                  ReadyToBootCallback,\r
-                  (VOID *) &ImageHandle,\r
-                  &ReadyToBootEvent\r
-                  );\r
-\r
   //\r
   // Install Hii packages.\r
   //\r
   //\r
   // Install Hii packages.\r
   //\r