Add Tper Reset Logic by using MOR bit.
authorqianouyang <qianouyang@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 12 Sep 2012 10:19:50 +0000 (10:19 +0000)
committerqianouyang <qianouyang@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 12 Sep 2012 10:19:50 +0000 (10:19 +0000)
Signed-off-by: Ouyang, Qian <Qian.Ouyang@intel.com>
Reviewed-by: Tian, Feng <feng.tian@intel.com>
             Dong, Guo <Guo.dong@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13727 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.h
MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf

index 8fa0b3f..17e2614 100644 (file)
@@ -18,6 +18,9 @@
 \r
 #include "AtaBus.h"\r
 \r
+UINT8   mMorControl;\r
+BOOLEAN mHasMor;\r
+\r
 //\r
 // ATA Bus Driver Binding Protocol Instance\r
 //\r
@@ -364,6 +367,19 @@ RegisterAtaDevice (
     if (EFI_ERROR (Status)) {\r
       goto Done;\r
     }\r
+    DEBUG ((EFI_D_INFO, "Successfully Install Storage Security Protocol on the ATA device\n"));\r
+  }\r
+\r
+  if (mHasMor) {\r
+    if (((mMorControl & 0x01) == 0x01) && ((AtaDevice->IdentifyData->trusted_computing_support & BIT0) != 0)) {\r
+      DEBUG ((EFI_D_INFO,\r
+              "mMorControl = %x, AtaDevice->IdentifyData->trusted_computing_support & BIT0 = %x\n",\r
+              mMorControl,\r
+              (AtaDevice->IdentifyData->trusted_computing_support & BIT0)\r
+              ));\r
+      DEBUG ((EFI_D_INFO, "Try to lock device by sending TPer Reset command...\n"));\r
+      InitiateTPerReset(AtaDevice);\r
+    }\r
   }\r
 \r
   gBS->OpenProtocol (\r
@@ -1638,6 +1654,7 @@ InitializeAtaBus(
   )\r
 {\r
   EFI_STATUS              Status;\r
+  UINTN                   DataSize;\r
 \r
   //\r
   // Install driver model protocol(s).\r
@@ -1652,5 +1669,196 @@ InitializeAtaBus(
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Get the MorControl bit.\r
+  //\r
+  DataSize = sizeof (mMorControl);\r
+  Status = gRT->GetVariable (\r
+                  MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
+                  &gEfiMemoryOverwriteControlDataGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &mMorControl\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_INFO, "AtaBus:gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));\r
+    mHasMor     = FALSE;\r
+    mMorControl = 0;\r
+    Status      = EFI_SUCCESS;\r
+  } else {\r
+    DEBUG ((EFI_D_INFO, "AtaBus:Get the gEfiMemoryOverwriteControlDataGuid = %x!!***\n", mMorControl));\r
+    mHasMor     = TRUE;\r
+  }\r
+\r
   return Status;\r
 }\r
+\r
+/**\r
+  Send TPer Reset command to reset eDrive to lock all protected bands.\r
+  Typically, there are 2 mechanism for resetting eDrive. They are:\r
+  1. TPer Reset through IEEE 1667 protocol.\r
+  2. TPer Reset through native TCG protocol.\r
+  This routine will detect what protocol the attached eDrive comform to, TCG or\r
+  IEEE 1667 protocol. Then send out TPer Reset command separately.\r
+\r
+  @param[in] AtaDevice    ATA_DEVICE pointer.\r
+\r
+**/\r
+VOID\r
+InitiateTPerReset (\r
+  IN   ATA_DEVICE       *AtaDevice\r
+  )\r
+{\r
+\r
+  EFI_STATUS                                   Status;\r
+  UINT8                                        *Buffer;\r
+  UINTN                                        XferSize;\r
+  UINTN                                        Len;\r
+  UINTN                                        Index;\r
+  BOOLEAN                                      TcgFlag;\r
+  BOOLEAN                                      IeeeFlag;\r
+  EFI_BLOCK_IO_PROTOCOL                        *BlockIo;\r
+  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL        *Ssp;\r
+  SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA  *Data;\r
+\r
+  Buffer        = NULL;\r
+  TcgFlag       = FALSE;\r
+  IeeeFlag      = FALSE;\r
+  Ssp           = &AtaDevice->StorageSecurity;\r
+  BlockIo       = &AtaDevice->BlockIo;\r
+\r
+  //\r
+  // ATA8-ACS 7.57.6.1 indicates the Transfer Length field requirements a multiple of 512.\r
+  // If the length of the TRUSTED RECEIVE parameter data is greater than the Transfer Length,\r
+  // then the device shall return the TRUSTED RECEIVE parameter data truncated to the requested Transfer Length.\r
+  //\r
+  Len           = ROUNDUP512(sizeof(SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA));\r
+  Buffer        = AllocateZeroPool(Len);\r
+\r
+  if (Buffer == NULL) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // When the Security Protocol field is set to 00h, and SP Specific is set to 0000h in a TRUSTED RECEIVE\r
+  // command, the device basic information data shall be returned.\r
+  //\r
+  Status = Ssp->ReceiveData (\r
+                  Ssp,\r
+                  BlockIo->Media->MediaId,\r
+                  100000000,                    // Timeout 10-sec\r
+                  0,                            // SecurityProtocol\r
+                  0,                            // SecurityProtocolSpecifcData\r
+                  Len,                          // PayloadBufferSize,\r
+                  Buffer,                       // PayloadBuffer\r
+                  &XferSize\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // In returned data, the ListLength field indicates the total length, in bytes,\r
+  // of the supported security protocol list.\r
+  //\r
+  Data = (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA*)Buffer;\r
+  Len  = ROUNDUP512(sizeof (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA) +\r
+                    (Data->SupportedSecurityListLength[0] << 8) +\r
+                    (Data->SupportedSecurityListLength[1])\r
+                    );\r
+\r
+  //\r
+  // Free original buffer and allocate new buffer.\r
+  //\r
+  FreePool(Buffer);\r
+  Buffer = AllocateZeroPool(Len);\r
+  if (Buffer == NULL) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Read full supported security protocol list from device.\r
+  //\r
+  Status = Ssp->ReceiveData (\r
+                  Ssp,\r
+                  BlockIo->Media->MediaId,\r
+                  100000000,                    // Timeout 10-sec\r
+                  0,                            // SecurityProtocol\r
+                  0,                            // SecurityProtocolSpecifcData\r
+                  Len,                          // PayloadBufferSize,\r
+                  Buffer,                       // PayloadBuffer\r
+                  &XferSize\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  Data = (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA*)Buffer;\r
+  Len  = (Data->SupportedSecurityListLength[0] << 8) + Data->SupportedSecurityListLength[1];\r
+\r
+  //\r
+  // Iterate full supported security protocol list to check if TCG or IEEE 1667 protocol\r
+  // is supported.\r
+  //\r
+  for (Index = 0; Index < Len; Index++) {\r
+    if (Data->SupportedSecurityProtocol[Index] == SECURITY_PROTOCOL_TCG) {\r
+      //\r
+      // Found a  TCG device.\r
+      //\r
+      TcgFlag = TRUE;\r
+      DEBUG ((EFI_D_INFO, "This device is a TCG protocol device\n"));\r
+      break;\r
+    }\r
+\r
+    if (Data->SupportedSecurityProtocol[Index] == SECURITY_PROTOCOL_IEEE1667) {\r
+      //\r
+      // Found a IEEE 1667 device.\r
+      //\r
+      IeeeFlag = TRUE;\r
+      DEBUG ((EFI_D_INFO, "This device is a IEEE 1667 protocol device\n"));\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (!TcgFlag && !IeeeFlag) {\r
+    DEBUG ((EFI_D_INFO, "Neither a TCG nor IEEE 1667 protocol device is found\n"));\r
+    goto Exit;\r
+  }\r
+\r
+  if (TcgFlag) {\r
+    //\r
+    // As long as TCG protocol is supported, send out a TPer Reset\r
+    // TCG command to the device via the TrustedSend command with a non-zero Transfer Length.\r
+    //\r
+    Status = Ssp->SendData (\r
+                    Ssp,\r
+                    BlockIo->Media->MediaId,\r
+                    100000000,                    // Timeout 10-sec\r
+                    SECURITY_PROTOCOL_TCG,        // SecurityProtocol\r
+                    0x0400,                       // SecurityProtocolSpecifcData\r
+                    512,                          // PayloadBufferSize,\r
+                    Buffer                        // PayloadBuffer\r
+                    );\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_INFO, "Send TPer Reset Command Successfully !\n"));\r
+    } else {\r
+      DEBUG ((EFI_D_INFO, "Send TPer Reset Command Fail !\n"));\r
+    }\r
+  }\r
+\r
+  if (IeeeFlag) {\r
+    //\r
+    // TBD : Perform a TPer Reset via IEEE 1667 Protocol\r
+    //\r
+    DEBUG ((EFI_D_INFO, "IEEE 1667 Protocol didn't support yet!\n"));\r
+  }\r
+\r
+Exit:\r
+\r
+  if (Buffer != NULL) {\r
+    FreePool(Buffer);\r
+  }\r
+}\r
index b64a3d3..d6b0ff8 100644 (file)
@@ -20,6 +20,7 @@
 \r
 #include <Uefi.h>\r
 \r
+#include <Guid/MemoryOverwriteControl.h>\r
 #include <Protocol/AtaPassThru.h>\r
 #include <Protocol/BlockIo.h>\r
 #include <Protocol/BlockIo2.h>\r
@@ -35,6 +36,7 @@
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DevicePathLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/TimerLib.h>\r
 \r
 #include <IndustryStandard/Atapi.h>\r
 #define ATA_SUB_TASK_SIGNATURE            SIGNATURE_32 ('A', 'S', 'T', 'S')\r
 #define IS_ALIGNED(addr, size)            (((UINTN) (addr) & (size - 1)) == 0)\r
 \r
+#define ROUNDUP512(x) (((x) % 512 == 0) ? (x) : ((x) / 512 + 1) * 512)\r
+\r
+#define SECURITY_PROTOCOL_TCG      0x02\r
+#define SECURITY_PROTOCOL_IEEE1667 0xEE\r
+\r
+//\r
+// ATA Supported Security Protocols List Description.\r
+// Refer to ATA8-ACS Spec 7.57.6.2 Table 69.\r
+//\r
+typedef struct  {\r
+  UINT8                            Reserved1[6];\r
+  UINT8                            SupportedSecurityListLength[2];\r
+  UINT8                            SupportedSecurityProtocol[1];\r
+} SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA;\r
+\r
 //\r
 // ATA bus data structure for ATA controller\r
 //\r
@@ -1042,4 +1059,20 @@ AtaStorageSecuritySendData (
   IN VOID                                     *PayloadBuffer\r
   );\r
 \r
+/**\r
+  Send TPer Reset command to reset eDrive to lock all protected bands.\r
+  Typically, there are 2 mechanism for resetting eDrive. They are:\r
+  1. TPer Reset through IEEE 1667 protocol.\r
+  2. TPer Reset through native TCG protocol.\r
+  This routine will detect what protocol the attached eDrive comform to, TCG or\r
+  IEEE 1667 protocol. Then send out TPer Reset command separately.\r
+\r
+  @param[in] AtaDevice    ATA_DEVICE pointer.\r
+\r
+**/\r
+VOID\r
+InitiateTPerReset (\r
+  IN   ATA_DEVICE       *AtaDevice\r
+  );\r
+\r
 #endif\r
index edc6df9..82f99e5 100644 (file)
@@ -5,7 +5,7 @@
 #  in UEFI spec 2.2. It installs Block IO and Disk Info protocol for each ATA device\r
 #  it enumerates and identifies successfully.\r
 #\r
-#  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -48,6 +48,7 @@
 [LibraryClasses]\r
   DevicePathLib\r
   UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
   MemoryAllocationLib\r
   BaseMemoryLib\r
   UefiLib\r
@@ -59,6 +60,7 @@
 [Guids]\r
   gEfiDiskInfoIdeInterfaceGuid                  # CONSUMES  ## GUID\r
   gEfiDiskInfoAhciInterfaceGuid                 # CONSUMES  ## GUID\r
+  gEfiMemoryOverwriteControlDataGuid            # CONSUMES  ## GUID\r
 \r
 [Protocols]\r
   gEfiDiskInfoProtocolGuid                      # BY_START\r