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