\r
\r
#include <PiPei.h>\r
+#include <Ppi/ReadOnlyVariable2.h>\r
\r
#include <Library/BaseLib.h>\r
#include <Library/BaseMemoryLib.h>\r
{\r
EFI_STATUS Status;\r
EFI_BOOT_MODE BootMode;\r
+ TREE_DEVICE_DETECTION TrEEDeviceDetection;\r
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;\r
+ UINTN Size;\r
+\r
+ if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {\r
+ DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Tpm is hide\n"));\r
+ return TPM_DEVICE_NULL;\r
+ }\r
\r
Status = PeiServicesGetBootMode (&BootMode);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
- // In S3, we rely on Setup option, because we save to Setup in normal boot.\r
+ // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot.\r
//\r
if (BootMode == BOOT_ON_S3_RESUME) {\r
DEBUG ((EFI_D_ERROR, "DetectTpmDevice: S3 mode\n"));\r
- return SetupTpmDevice;\r
- }\r
\r
- if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {\r
- DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Tpm is hide\n"));\r
- return TPM_DEVICE_NULL;\r
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Size = sizeof(TREE_DEVICE_DETECTION);\r
+ ZeroMem (&TrEEDeviceDetection, sizeof(TrEEDeviceDetection));\r
+ Status = VariablePpi->GetVariable (\r
+ VariablePpi,\r
+ TREE_DEVICE_DETECTION_NAME,\r
+ &gTrEEConfigFormSetGuid,\r
+ NULL,\r
+ &Size,\r
+ &TrEEDeviceDetection\r
+ );\r
+ if (!EFI_ERROR (Status) &&\r
+ (TrEEDeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) &&\r
+ (TrEEDeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX)) {\r
+ DEBUG ((EFI_D_ERROR, "TpmDevice from DeviceDetection: %x\n", TrEEDeviceDetection.TpmDeviceDetected));\r
+ return TrEEDeviceDetection.TpmDeviceDetected;\r
+ }\r
}\r
\r
DEBUG ((EFI_D_ERROR, "DetectTpmDevice:\n"));\r
- if ((!IsDtpmPresent ()) || (SetupTpmDevice == TPM_DEVICE_NULL)) {\r
+ if (!IsDtpmPresent ()) {\r
// dTPM not available\r
return TPM_DEVICE_NULL;\r
}\r
return TPM_DEVICE_2_0_DTPM;\r
}\r
\r
- Status = Tpm12Startup (TPM_ST_CLEAR);\r
+ if (BootMode == BOOT_ON_S3_RESUME) {\r
+ Status = Tpm12Startup (TPM_ST_STATE);\r
+ } else {\r
+ Status = Tpm12Startup (TPM_ST_CLEAR);\r
+ }\r
if (EFI_ERROR (Status)) {\r
return TPM_DEVICE_2_0_DTPM;\r
}\r
help = STRING_TOKEN(STR_TREE_HELP),\r
classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,\r
\r
- varstore TREE_CONFIGURATION,\r
+ efivarstore TREE_CONFIGURATION,\r
varid = TREE_CONFIGURATION_VARSTORE_ID,\r
+ attribute = 0x03, // EFI variable attribures EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE\r
name = TREE_CONFIGURATION,\r
guid = TREE_CONFIG_FORM_SET_GUID;\r
\r
prompt = STRING_TOKEN(STR_TREE_DEVICE_PROMPT),\r
help = STRING_TOKEN(STR_TREE_DEVICE_HELP),\r
flags = INTERACTIVE,\r
- option text = STRING_TOKEN(STR_TREE_TPM_DISABLE), value = TPM_DEVICE_NULL, flags = RESET_REQUIRED;\r
option text = STRING_TOKEN(STR_TREE_TPM_1_2), value = TPM_DEVICE_1_2, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\r
option text = STRING_TOKEN(STR_TREE_TPM_2_0_DTPM), value = TPM_DEVICE_2_0_DTPM, flags = RESET_REQUIRED;\r
endoneof;\r
subtitle text = STRING_TOKEN(STR_NULL);\r
subtitle text = STRING_TOKEN(STR_TREE_PP_OPERATION);\r
\r
- oneof varid = TREE_CONFIGURATION.Tpm2Operation,\r
+ oneof name = Tpm2Operation,\r
+ questionid = KEY_TPM2_OPERATION,\r
prompt = STRING_TOKEN(STR_TREE_OPERATION),\r
help = STRING_TOKEN(STR_TREE_OPERATION_HELP),\r
- flags = INTERACTIVE,\r
+ flags = INTERACTIVE | NUMERIC_SIZE_1,\r
option text = STRING_TOKEN(STR_TREE_NO_ACTION), value = TREE_PHYSICAL_PRESENCE_NO_ACTION, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\r
option text = STRING_TOKEN(STR_TREE_CLEAR), value = TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR, flags = RESET_REQUIRED;\r
endoneof;\r
EFI_STATUS Status;\r
TREE_CONFIG_PRIVATE_DATA *PrivateData;\r
TREE_CONFIGURATION TrEEConfiguration;\r
+ TREE_DEVICE_DETECTION TrEEDeviceDetection;\r
UINTN Index;\r
UINTN DataSize;\r
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;\r
\r
Status = gBS->OpenProtocol (\r
ImageHandle,\r
&TrEEConfiguration\r
);\r
if (EFI_ERROR (Status)) {\r
+ //\r
+ // Variable not ready, set default value\r
+ //\r
+ TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;\r
}\r
+\r
//\r
- // We should always reinit PP request.\r
+ // Validation\r
//\r
- TrEEConfiguration.Tpm2Operation = TREE_PHYSICAL_PRESENCE_NO_ACTION;\r
+ if ((TrEEConfiguration.TpmDevice > TPM_DEVICE_MAX) || (TrEEConfiguration.TpmDevice < TPM_DEVICE_MIN)) {\r
+ TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;\r
+ }\r
\r
//\r
- // Sync data from PCD to variable, so that we do not need detect again in S3 phase.\r
+ // Save to variable so platform driver can get it.\r
//\r
+ Status = gRT->SetVariable (\r
+ TREE_STORAGE_NAME,\r
+ &gTrEEConfigFormSetGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ sizeof(TrEEConfiguration),\r
+ &TrEEConfiguration\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "TrEEConfigDriver: Fail to set TREE_STORAGE_NAME\n"));\r
+ }\r
\r
//\r
- // Get data from PCD to make sure data consistant - platform driver is suppose to construct this PCD accroding to Variable\r
+ // Sync data from PCD to variable, so that we do not need detect again in S3 phase.\r
//\r
+ TrEEDeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL;\r
for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {\r
if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {\r
- TrEEConfiguration.TpmDevice = mTpmInstanceId[Index].TpmDevice;\r
+ TrEEDeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice;\r
break;\r
}\r
}\r
\r
+ PrivateData->TpmDeviceDetected = TrEEDeviceDetection.TpmDeviceDetected;\r
+\r
//\r
// Save to variable so platform driver can get it.\r
//\r
Status = gRT->SetVariable (\r
- TREE_STORAGE_NAME,\r
+ TREE_DEVICE_DETECTION_NAME,\r
&gTrEEConfigFormSetGuid,\r
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- sizeof(TrEEConfiguration),\r
- &TrEEConfiguration\r
+ sizeof(TrEEDeviceDetection),\r
+ &TrEEDeviceDetection\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "TrEEConfigDriver: Fail to set TREE_DEVICE_DETECTION_NAME\n"));\r
+ Status = gRT->SetVariable (\r
+ TREE_DEVICE_DETECTION_NAME,\r
+ &gTrEEConfigFormSetGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ 0,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ //\r
+ // We should lock TrEEDeviceDetection, because it contains information needed at S3.\r
+ //\r
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = VariableLockProtocol->RequestToLock (\r
+ VariableLockProtocol,\r
+ TREE_DEVICE_DETECTION_NAME,\r
+ &gTrEEConfigFormSetGuid\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
\r
//\r
// Install TrEE configuration form\r
[Protocols]\r
gEfiHiiConfigAccessProtocolGuid ## PRODUCES\r
gEfiHiiConfigRoutingProtocolGuid ## CONSUMES\r
+ gEdkiiVariableLockProtocolGuid ## CONSUMES\r
\r
[Pcd]\r
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid\r
OUT EFI_STRING *Results\r
)\r
{\r
- EFI_STATUS Status;\r
- UINTN BufferSize;\r
- TREE_CONFIGURATION Configuration;\r
- TREE_CONFIG_PRIVATE_DATA *PrivateData;\r
- EFI_STRING ConfigRequestHdr;\r
- EFI_STRING ConfigRequest;\r
- BOOLEAN AllocatedRequest;\r
- UINTN Size;\r
- UINTN Index;\r
-\r
- if (Progress == NULL || Results == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Progress = Request;\r
- if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTrEEConfigFormSetGuid, TREE_STORAGE_NAME)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- ConfigRequestHdr = NULL;\r
- ConfigRequest = NULL;\r
- AllocatedRequest = FALSE;\r
- Size = 0;\r
-\r
- PrivateData = TREE_CONFIG_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
- // \r
- BufferSize = sizeof (Configuration);\r
- Status = gRT->GetVariable (\r
- TREE_STORAGE_NAME,\r
- &gTrEEConfigFormSetGuid,\r
- NULL,\r
- &BufferSize,\r
- &Configuration\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Get data from PCD to make sure data consistant - platform driver is suppose to construct this PCD accroding to Variable\r
- //\r
- for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {\r
- if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {\r
- Configuration.TpmDevice = mTpmInstanceId[Index].TpmDevice;\r
- break;\r
- }\r
- }\r
-\r
- BufferSize = sizeof (Configuration);\r
- ConfigRequest = Request;\r
- if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
- //\r
- // Request has no request element, construct full request string.\r
- // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
- // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
- //\r
- ConfigRequestHdr = HiiConstructConfigHdr (&gTrEEConfigFormSetGuid, TREE_STORAGE_NAME, PrivateData->DriverHandle);\r
- Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
- ConfigRequest = AllocateZeroPool (Size);\r
- ASSERT (ConfigRequest != NULL);\r
- AllocatedRequest = TRUE;\r
- UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);\r
- FreePool (ConfigRequestHdr);\r
- }\r
-\r
- Status = gHiiConfigRouting->BlockToConfig (\r
- gHiiConfigRouting,\r
- ConfigRequest,\r
- (UINT8 *) &Configuration,\r
- BufferSize,\r
- Results,\r
- Progress\r
- );\r
- //\r
- // Free the allocated config request string.\r
- //\r
- if (AllocatedRequest) {\r
- FreePool (ConfigRequest);\r
- }\r
- //\r
- // Set Progress string to the original request string.\r
- //\r
- if (Request == NULL) {\r
- *Progress = NULL;\r
- } else if (StrStr (Request, L"OFFSET") == NULL) {\r
- *Progress = Request + StrLen (Request);\r
- }\r
-\r
- return Status;\r
+ return EFI_UNSUPPORTED;\r
}\r
\r
/**\r
OUT EFI_STRING *Progress\r
)\r
{\r
- EFI_STATUS Status;\r
- UINTN BufferSize;\r
- TREE_CONFIGURATION TrEEConfiguration;\r
-\r
- if (Configuration == NULL || Progress == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Progress = Configuration;\r
- if (!HiiIsConfigHdrMatch (Configuration, &gTrEEConfigFormSetGuid, TREE_STORAGE_NAME)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- BufferSize = sizeof (TrEEConfiguration);\r
- Status = gRT->GetVariable (\r
- TREE_STORAGE_NAME,\r
- &gTrEEConfigFormSetGuid,\r
- NULL,\r
- &BufferSize,\r
- &TrEEConfiguration\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
- //\r
- BufferSize = sizeof (TREE_CONFIGURATION);\r
- Status = gHiiConfigRouting->ConfigToBlock (\r
- gHiiConfigRouting,\r
- Configuration,\r
- (UINT8 *) &TrEEConfiguration,\r
- &BufferSize,\r
- Progress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Save to variable so platform driver can get it.\r
- //\r
- Status = gRT->SetVariable (\r
- TREE_STORAGE_NAME,\r
- &gTrEEConfigFormSetGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- sizeof(TrEEConfiguration),\r
- &TrEEConfiguration\r
- );\r
-\r
- SaveTrEEPpRequest (TrEEConfiguration.Tpm2Operation\r
- );\r
-\r
- return Status;\r
+ return EFI_UNSUPPORTED;\r
}\r
\r
/**\r
if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
-\r
- if ((Action != EFI_BROWSER_ACTION_CHANGED) ||\r
- (QuestionId != KEY_TPM_DEVICE)) {\r
- return EFI_UNSUPPORTED;\r
+ \r
+ if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+ if (QuestionId == KEY_TPM_DEVICE) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ if (QuestionId == KEY_TPM2_OPERATION) {\r
+ return SaveTrEEPpRequest (Value->u8);\r
+ }\r
}\r
\r
- return EFI_SUCCESS;\r
+ return EFI_UNSUPPORTED;\r
}\r
\r
/**\r
\r
PrivateData->HiiHandle = HiiHandle;\r
\r
+ //\r
+ // Update static data\r
+ //\r
+ switch (PrivateData->TpmDeviceDetected) {\r
+ case TPM_DEVICE_NULL:\r
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"Not Found", NULL);\r
+ break;\r
+ case TPM_DEVICE_1_2:\r
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"TPM 1.2", NULL);\r
+ break;\r
+ case TPM_DEVICE_2_0_DTPM:\r
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"TPM 2.0 (DTPM)", NULL);\r
+ break;\r
+ default:\r
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"Unknown", NULL);\r
+ break;\r
+ }\r
+\r
return EFI_SUCCESS; \r
}\r
\r
#include <Protocol/HiiConfigAccess.h>\r
#include <Protocol/HiiConfigRouting.h>\r
#include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/VariableLock.h>\r
\r
#include <Library/BaseLib.h>\r
#include <Library/BaseMemoryLib.h>\r
EFI_HII_HANDLE HiiHandle;\r
EFI_HANDLE DriverHandle; \r
\r
+ UINT8 TpmDeviceDetected;\r
} TREE_CONFIG_PRIVATE_DATA;\r
\r
extern TREE_CONFIG_PRIVATE_DATA mTrEEConfigPrivateDateTemplate;\r
#define TREE_CONFIGURATION_FORM_ID 0x0001\r
\r
#define KEY_TPM_DEVICE 0x2000\r
+#define KEY_TPM2_OPERATION 0x2001\r
\r
#define TPM_DEVICE_NULL 0\r
#define TPM_DEVICE_1_2 1\r
#define TPM_DEVICE_2_0_DTPM 2\r
+#define TPM_DEVICE_MIN TPM_DEVICE_1_2\r
#define TPM_DEVICE_MAX TPM_DEVICE_2_0_DTPM\r
#define TPM_DEVICE_DEFAULT TPM_DEVICE_1_2\r
\r
//\r
-// Nv Data structure referenced by IFR\r
+// Nv Data structure referenced by IFR, TPM device user desired\r
//\r
typedef struct {\r
UINT8 TpmDevice;\r
- UINT8 Tpm2Operation;\r
} TREE_CONFIGURATION;\r
\r
+//\r
+// Variable saved for S3, TPM detected, only valid in S3 path.\r
+// This variable is ReadOnly.\r
+//\r
+typedef struct {\r
+ UINT8 TpmDeviceDetected;\r
+} TREE_DEVICE_DETECTION;\r
+\r
#define TREE_STORAGE_NAME L"TREE_CONFIGURATION"\r
+#define TREE_DEVICE_DETECTION_NAME L"TREE_DEVICE_DETECTION"\r
\r
#define TPM_INSTANCE_ID_LIST { \\r
{TPM_DEVICE_INTERFACE_NONE, TPM_DEVICE_NULL}, \\r
//\r
// Validation\r
//\r
- if (TrEEConfiguration.TpmDevice > TPM_DEVICE_MAX) {\r
- TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;\r
+ if ((TrEEConfiguration.TpmDevice > TPM_DEVICE_MAX) || (TrEEConfiguration.TpmDevice < TPM_DEVICE_MIN)) {\r
+ TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;\r
}\r
\r
//\r
\r
if (PcdGetBool (PcdTpmAutoDetection)) {\r
TpmDevice = DetectTpmDevice (TrEEConfiguration.TpmDevice);\r
- DEBUG ((EFI_D_ERROR, "TrEEConfiguration.TpmDevice final: %x\n", TpmDevice));\r
- TrEEConfiguration.TpmDevice = TpmDevice;\r
+ DEBUG ((EFI_D_ERROR, "TpmDevice final: %x\n", TpmDevice));\r
+ if (TpmDevice != TPM_DEVICE_NULL) {\r
+ TrEEConfiguration.TpmDevice = TpmDevice;\r
+ }\r
+ } else {\r
+ TpmDevice = TrEEConfiguration.TpmDevice;\r
}\r
\r
//\r
// This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase.\r
// Using DynamicPcd instead.\r
//\r
+ // NOTE: TrEEConfiguration variable contains the desired TpmDevice type,\r
+ // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice type\r
+ //\r
for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {\r
- if (TrEEConfiguration.TpmDevice == mTpmInstanceId[Index].TpmDevice) {\r
+ if (TpmDevice == mTpmInstanceId[Index].TpmDevice) {\r
Size = sizeof(mTpmInstanceId[Index].TpmInstanceGuid);\r
PcdSetPtr (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid);\r
- DEBUG ((EFI_D_ERROR, "TrEEConfiguration.TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));\r
+ DEBUG ((EFI_D_ERROR, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));\r
break;\r
}\r
}\r