]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c
SecurityPkg OpalPasswordSmm: Consume SmmIoLib.
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPasswordSmm / OpalPasswordSmm.c
index 57d10a17b77a42d60c44be990371e58697ace3d7..0ea92b15c067720cee0c94bb5a05d186dac36e7d 100644 (file)
@@ -177,12 +177,14 @@ ExtractDeviceInfoFromDevicePath (
   TRUE means that the device is partially or fully locked.\r
   This will perform a Level 0 Discovery and parse the locking feature descriptor\r
 \r
-  @param[in]      OpalDev        Opal object to determine if locked\r
+  @param[in]      OpalDev             Opal object to determine if locked\r
+  @param[out]     BlockSidSupported   Whether device support BlockSid feature.\r
 \r
 **/\r
 BOOLEAN\r
 IsOpalDeviceLocked(\r
-  OPAL_SMM_DEVICE    *OpalDev\r
+  OPAL_SMM_DEVICE    *OpalDev,\r
+  BOOLEAN            *BlockSidSupported\r
   )\r
 {\r
   OPAL_SESSION                   Session;\r
@@ -200,7 +202,8 @@ IsOpalDeviceLocked(
   }\r
 \r
   OpalDev->OpalBaseComId = OpalBaseComId;\r
-  Session.OpalBaseComId = OpalBaseComId;\r
+  Session.OpalBaseComId  = OpalBaseComId;\r
+  *BlockSidSupported     = SupportedAttributes.BlockSid == 1 ? TRUE : FALSE;\r
 \r
   Ret = OpalGetLockingInfo(&Session, &LockingFeature);\r
   if (Ret != TcgResultSuccess) {\r
@@ -343,6 +346,7 @@ SmmUnlockOpalPassword (
   UINTN                          MemoryBase;\r
   UINTN                          MemoryLength;\r
   OPAL_SESSION                   Session;\r
+  BOOLEAN                        BlockSidSupport;\r
 \r
   ZeroMem (StorePcieConfDataList, sizeof (StorePcieConfDataList));\r
   Status = EFI_DEVICE_ERROR;\r
@@ -428,25 +432,26 @@ SmmUnlockOpalPassword (
     }\r
 \r
     Status = EFI_DEVICE_ERROR;\r
-    if (IsOpalDeviceLocked(OpalDev)) {\r
+    BlockSidSupport = FALSE;\r
+    if (IsOpalDeviceLocked (OpalDev, &BlockSidSupport)) {\r
       ZeroMem(&Session, sizeof(Session));\r
       Session.Sscp = &OpalDev->Sscp;\r
       Session.MediaId = 0;\r
       Session.OpalBaseComId = OpalDev->OpalBaseComId;\r
 \r
-      if (mSendBlockSID) {\r
-        Result = OpalBlockSid (&Session, TRUE);\r
-        if (Result != TcgResultSuccess) {\r
-          break;\r
-        }\r
-      }\r
-\r
       Result = OpalSupportUnlock (&Session, OpalDev->Password, OpalDev->PasswordLength, NULL);\r
       if (Result == TcgResultSuccess) {\r
         Status = EFI_SUCCESS;\r
       }\r
     }\r
 \r
+    if (mSendBlockSID && BlockSidSupport) {\r
+      Result = OpalBlockSid (&Session, TRUE);\r
+      if (Result != TcgResultSuccess) {\r
+        break;\r
+      }\r
+    }\r
+\r
     if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
       if (SubClassCode == PCI_CLASS_MASS_STORAGE_NVM) {\r
         Status = NvmeControllerExit (&mNvmeContext);\r
@@ -475,6 +480,53 @@ done:
   return Status;\r
 }\r
 \r
+/**\r
+  The function extracts device information from OpalDeviceList and creat SmmDeviceList used for S3.\r
+\r
+  @param[in]       OpalDeviceList   Opal device list created at POST which contains the information of OPAL_DISK_AND_PASSWORD_INFO\r
+  @param[in,out]   SmmDeviceList    Opal Smm device list to be created and used for unlocking devices at S3 resume.\r
+\r
+  @retval EFI_SUCCESS            Create SmmDeviceList successfully.\r
+  @retval Others                 Other execution results.\r
+**/\r
+EFI_STATUS\r
+CreateSmmDeviceList (\r
+  IN     LIST_ENTRY                 *OpalDeviceList,\r
+  IN OUT LIST_ENTRY                 *SmmDeviceList\r
+  )\r
+{\r
+  LIST_ENTRY                        *Entry;\r
+  OPAL_DISK_AND_PASSWORD_INFO       *PciDev;\r
+  OPAL_SMM_DEVICE                   *SmmDev;\r
+\r
+  for (Entry = OpalDeviceList->ForwardLink; Entry != OpalDeviceList; Entry = Entry->ForwardLink) {\r
+    PciDev = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
+\r
+    SmmDev = AllocateZeroPool (sizeof (OPAL_SMM_DEVICE));\r
+    if (SmmDev == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    SmmDev->Signature = OPAL_SMM_DEVICE_SIGNATURE;\r
+\r
+    ExtractDeviceInfoFromDevicePath(&PciDev->OpalDevicePath, SmmDev);\r
+\r
+    SmmDev->PasswordLength = PciDev->PasswordLength;\r
+    CopyMem(&(SmmDev->Password), PciDev->Password, OPAL_PASSWORD_MAX_LENGTH);\r
+\r
+    SmmDev->Sscp.ReceiveData = SecurityReceiveData;\r
+    SmmDev->Sscp.SendData = SecuritySendData;\r
+\r
+    DEBUG ((DEBUG_INFO, "Opal SMM: Insert device node to SmmDeviceList:\n"));\r
+    DEBUG ((DEBUG_INFO, "DeviceType:%x, Bus:%d, Dev:%d, Fun:%d\n", \\r
+      SmmDev->DeviceType, SmmDev->BusNum, SmmDev->DevNum, SmmDev->FuncNum));\r
+    DEBUG ((DEBUG_INFO, "SataPort:%x, MultiplierPort:%x, NvmeNamespaceId:%x\n", \\r
+      SmmDev->SataPort, SmmDev->SataPortMultiplierPort, SmmDev->NvmeNamespaceId));\r
+\r
+    InsertHeadList (SmmDeviceList, &SmmDev->Link);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   Main entry point for an SMM handler dispatch or communicate-based callback.\r
@@ -513,7 +565,6 @@ S3SleepEntryCallBack (
   UINT64                            Address;\r
   S3_BOOT_SCRIPT_LIB_WIDTH          Width;\r
   UINT32                            Data;\r
-  OPAL_DISK_AND_PASSWORD_INFO       *PciDev;\r
   OPAL_HC_PCI_REGISTER_SAVE         *HcRegisterSaveListPtr;\r
   UINTN                             Count;\r
   OPAL_SMM_DEVICE                   *SmmDev;\r
@@ -522,25 +573,28 @@ S3SleepEntryCallBack (
   Status   = EFI_SUCCESS;\r
 \r
   mOpalDeviceList = OpalSupportGetOpalDeviceList();\r
+  if (IsListEmpty (mOpalDeviceList)) {\r
+    //\r
+    // No Opal enabled device. Do nothing.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
-  for (Entry = mOpalDeviceList->ForwardLink; Entry != mOpalDeviceList; Entry = Entry->ForwardLink) {\r
-    PciDev   = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
-\r
-    SmmDev = AllocateZeroPool (sizeof (OPAL_SMM_DEVICE));\r
-    if (SmmDev == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+  if (IsListEmpty (&mSmmDeviceList)) {\r
+    //\r
+    // mSmmDeviceList for S3 is empty, creat it by mOpalDeviceList.\r
+    //\r
+    Status = CreateSmmDeviceList (mOpalDeviceList, &mSmmDeviceList);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
     }\r
-    SmmDev->Signature = OPAL_SMM_DEVICE_SIGNATURE;\r
-\r
-    ExtractDeviceInfoFromDevicePath(&PciDev->OpalDevicePath, SmmDev);\r
-\r
-    SmmDev->PasswordLength = PciDev->PasswordLength;\r
-    CopyMem(&(SmmDev->Password), PciDev->Password, OPAL_PASSWORD_MAX_LENGTH);\r
-\r
-    SmmDev->Sscp.ReceiveData = SecurityReceiveData;\r
-    SmmDev->Sscp.SendData = SecuritySendData;\r
+  }\r
 \r
-    InsertHeadList (&mSmmDeviceList, &SmmDev->Link);\r
+  //\r
+  // Go through SmmDeviceList to save register data for S3\r
+  //\r
+  for (Entry = mSmmDeviceList.ForwardLink; Entry != &mSmmDeviceList; Entry = Entry->ForwardLink) {\r
+    SmmDev = BASE_CR (Entry, OPAL_SMM_DEVICE, Link);\r
 \r
     if (SmmDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
       continue;\r
@@ -584,10 +638,8 @@ S3SleepEntryCallBack (
     }\r
   }\r
 \r
-  if (!IsListEmpty (mOpalDeviceList)) {\r
-    Status = S3BootScriptSaveIoWrite (S3BootScriptWidthUint8, 0xB2, 1, &mSwSmiValue);\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
+  Status = S3BootScriptSaveIoWrite (S3BootScriptWidthUint8, 0xB2, 1, &mSwSmiValue);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   return Status;\r
 }\r