blob: 4336604d0d1e2aa02ddd205d5ca2ac52da24a197 [file] [log] [blame]
/** @file
Implementation of the HII for the Opal UEFI Driver.
Copyright (c) 2016 - 2018, 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
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "OpalHii.h"
//
// Character definitions
//
#define UPPER_LOWER_CASE_OFFSET 0x20
//
// This is the generated IFR binary Data for each formset defined in VFR.
// This Data array is ready to be used as input of HiiAddPackages() to
// create a packagelist (which contains Form packages, String packages, etc).
//
extern UINT8 OpalPasswordFormBin[];
//
// This is the generated String package Data for all .UNI files.
// This Data array is ready to be used as input of HiiAddPackages() to
// create a packagelist (which contains Form packages, String packages, etc).
//
extern UINT8 OpalPasswordDxeStrings[];
CHAR16 OpalPasswordStorageName[] = L"OpalHiiConfig";
EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol;
//
// Handle to the list of HII packages (forms and strings) for this driver
//
EFI_HII_HANDLE gHiiPackageListHandle = NULL;
//
// Package List GUID containing all form and string packages
//
const EFI_GUID gHiiPackageListGuid = PACKAGE_LIST_GUID;
const EFI_GUID gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;
//
// Structure that contains state of the HII
// This structure is updated by Hii.cpp and its contents
// is rendered in the HII.
//
OPAL_HII_CONFIGURATION gHiiConfiguration;
//
// The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL
//
HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath = {
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8)(sizeof(VENDOR_DEVICE_PATH)),
(UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)
}
},
OPAL_PASSWORD_CONFIG_GUID
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{
(UINT8)(END_DEVICE_PATH_LENGTH),
(UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
}
}
};
/**
Get saved OPAL request.
@param[in] OpalDisk The disk needs to get the saved OPAL request.
@param[out] OpalRequest OPAL request got.
**/
VOID
GetSavedOpalRequest (
IN OPAL_DISK *OpalDisk,
OUT OPAL_REQUEST *OpalRequest
)
{
EFI_STATUS Status;
OPAL_REQUEST_VARIABLE *TempVariable;
OPAL_REQUEST_VARIABLE *Variable;
UINTN VariableSize;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable;
UINTN DevicePathSizeInVariable;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN DevicePathSize;
DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
Variable = NULL;
VariableSize = 0;
Status = GetVariable2 (
OPAL_REQUEST_VARIABLE_NAME,
&gHiiSetupVariableGuid,
(VOID **) &Variable,
&VariableSize
);
if (EFI_ERROR (Status) || (Variable == NULL)) {
return;
}
TempVariable = Variable;
while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&
(VariableSize >= TempVariable->Length) &&
(TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) {
DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);
DevicePath = OpalDisk->OpalDevicePath;
DevicePathSize = GetDevicePathSize (DevicePath);
if ((DevicePathSize == DevicePathSizeInVariable) &&
(CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) {
//
// Found the node for the OPAL device.
// Get the OPAL request.
//
CopyMem (OpalRequest, &TempVariable->OpalRequest, sizeof (OPAL_REQUEST));
DEBUG ((
DEBUG_INFO,
"OpalRequest got: 0x%x\n",
*OpalRequest
));
break;
}
VariableSize -= TempVariable->Length;
TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length);
}
FreePool (Variable);
DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));
}
/**
Save OPAL request.
@param[in] OpalDisk The disk has OPAL request to save.
@param[in] OpalRequest OPAL request to save.
**/
VOID
SaveOpalRequest (
IN OPAL_DISK *OpalDisk,
IN OPAL_REQUEST OpalRequest
)
{
EFI_STATUS Status;
OPAL_REQUEST_VARIABLE *TempVariable;
UINTN TempVariableSize;
OPAL_REQUEST_VARIABLE *Variable;
UINTN VariableSize;
OPAL_REQUEST_VARIABLE *NewVariable;
UINTN NewVariableSize;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable;
UINTN DevicePathSizeInVariable;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN DevicePathSize;
DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
DEBUG ((
DEBUG_INFO,
"OpalRequest to save: 0x%x\n",
OpalRequest
));
Variable = NULL;
VariableSize = 0;
NewVariable = NULL;
NewVariableSize = 0;
Status = GetVariable2 (
OPAL_REQUEST_VARIABLE_NAME,
&gHiiSetupVariableGuid,
(VOID **) &Variable,
&VariableSize
);
if (!EFI_ERROR (Status) && (Variable != NULL)) {
TempVariable = Variable;
TempVariableSize = VariableSize;
while ((TempVariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&
(TempVariableSize >= TempVariable->Length) &&
(TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) {
DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);
DevicePath = OpalDisk->OpalDevicePath;
DevicePathSize = GetDevicePathSize (DevicePath);
if ((DevicePathSize == DevicePathSizeInVariable) &&
(CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) {
//
// Found the node for the OPAL device.
// Update the OPAL request.
//
CopyMem (&TempVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
NewVariable = Variable;
NewVariableSize = VariableSize;
break;
}
TempVariableSize -= TempVariable->Length;
TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length);
}
if (NewVariable == NULL) {
//
// The node for the OPAL device is not found.
// Create node for the OPAL device.
//
DevicePath = OpalDisk->OpalDevicePath;
DevicePathSize = GetDevicePathSize (DevicePath);
NewVariableSize = VariableSize + sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize;
NewVariable = AllocatePool (NewVariableSize);
ASSERT (NewVariable != NULL);
CopyMem (NewVariable, Variable, VariableSize);
TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) NewVariable + VariableSize);
TempVariable->Length = (UINT32) (sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize);
CopyMem (&TempVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
CopyMem (DevicePathInVariable, DevicePath, DevicePathSize);
}
} else {
DevicePath = OpalDisk->OpalDevicePath;
DevicePathSize = GetDevicePathSize (DevicePath);
NewVariableSize = sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize;
NewVariable = AllocatePool (NewVariableSize);
ASSERT (NewVariable != NULL);
NewVariable->Length = (UINT32) (sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize);
CopyMem (&NewVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) NewVariable + sizeof (OPAL_REQUEST_VARIABLE));
CopyMem (DevicePathInVariable, DevicePath, DevicePathSize);
}
Status = gRT->SetVariable (
OPAL_REQUEST_VARIABLE_NAME,
(EFI_GUID *) &gHiiSetupVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
NewVariableSize,
NewVariable
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OpalRequest variable set failed (%r)\n", Status));
}
if (NewVariable != Variable) {
FreePool (NewVariable);
}
if (Variable != NULL) {
FreePool (Variable);
}
DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));
}
/**
Sets the current system state of global config variables.
**/
VOID
HiiSetCurrentConfiguration(
VOID
)
{
UINT32 PpStorageFlag;
EFI_STRING NewString;
gHiiConfiguration.NumDisks = GetDeviceCount();
//
// Update the BlockSID status string.
//
PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();
if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_ENABLED), NULL);
if (NewString == NULL) {
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
return;
}
} else {
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISABLED), NULL);
if (NewString == NULL) {
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
return;
}
}
HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS1), NewString, NULL);
FreePool (NewString);
if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) != 0) {
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), NULL);
if (NewString == NULL) {
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
return;
}
} else {
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), NULL);
if (NewString == NULL) {
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
return;
}
}
HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS2), NewString, NULL);
FreePool (NewString);
if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) != 0) {
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), NULL);
if (NewString == NULL) {
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
return;
}
} else {
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), NULL);
if (NewString == NULL) {
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
return;
}
}
HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS3), NewString, NULL);
FreePool (NewString);
}
/**
Install the HII related resources.
@retval EFI_SUCCESS Install all the resources success.
@retval other Error occur when install the resources.
**/
EFI_STATUS
HiiInstall(
VOID
)
{
EFI_STATUS Status;
EFI_HANDLE DriverHandle;
//
// Clear the global configuration.
//
ZeroMem(&gHiiConfiguration, sizeof(gHiiConfiguration));
//
// Obtain the driver handle that the BIOS assigned us
//
DriverHandle = HiiGetDriverImageHandleCB();
//
// Populate the config access protocol with the three functions we are publishing
//
gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;
gHiiConfigAccessProtocol.RouteConfig = RouteConfig;
gHiiConfigAccessProtocol.Callback = DriverCallback;
//
// Associate the required protocols with our driver handle
//
Status = gBS->InstallMultipleProtocolInterfaces(
&DriverHandle,
&gEfiHiiConfigAccessProtocolGuid,
&gHiiConfigAccessProtocol, // HII callback
&gEfiDevicePathProtocolGuid,
&gHiiVendorDevicePath, // required for HII callback allow all disks to be shown in same hii
NULL
);
if (EFI_ERROR(Status)) {
return Status;
}
return OpalHiiAddPackages();
}
/**
Install the HII form and string packages.
@retval EFI_SUCCESS Install all the resources success.
@retval EFI_OUT_OF_RESOURCES Out of resource error.
**/
EFI_STATUS
OpalHiiAddPackages(
VOID
)
{
EFI_HANDLE DriverHandle;
CHAR16 *NewString;
DriverHandle = HiiGetDriverImageHandleCB();
//
// Publish the HII form and HII string packages
//
gHiiPackageListHandle = HiiAddPackages(
&gHiiPackageListGuid,
DriverHandle,
OpalPasswordDxeStrings,
OpalPasswordFormBin,
(VOID*)NULL
);
//
// Make sure the packages installed successfully
//
if (gHiiPackageListHandle == NULL) {
DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));
return EFI_OUT_OF_RESOURCES;
}
//
// Update Version String in main window
//
NewString = HiiGetDriverNameCB ();
if (HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_MAIN_OPAL_VERSION), NewString, NULL) == 0) {
DEBUG ((DEBUG_INFO, "OpalHiiAddPackages: HiiSetString( ) failed\n"));
return EFI_OUT_OF_RESOURCES;
}
return EFI_SUCCESS;
}
/**
Uninstall the HII capability.
@retval EFI_SUCCESS Uninstall all the resources success.
@retval others Other errors occur when unistall the hii resource.
**/
EFI_STATUS
HiiUninstall(
VOID
)
{
EFI_STATUS Status;
//
// Remove the packages we've provided to the BIOS
//
HiiRemovePackages(gHiiPackageListHandle);
//
// Remove the protocols from our driver handle
//
Status = gBS->UninstallMultipleProtocolInterfaces(
HiiGetDriverImageHandleCB(),
&gEfiHiiConfigAccessProtocolGuid,
&gHiiConfigAccessProtocol, // HII callback
&gEfiDevicePathProtocolGuid,
&gHiiVendorDevicePath, // required for HII callback
NULL
);
if (EFI_ERROR(Status)) {
DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));
}
return Status;
}
/**
Updates the main menu form.
@retval EFI_SUCCESS update the main form success.
**/
EFI_STATUS
HiiPopulateMainMenuForm (
VOID
)
{
UINT8 Index;
CHAR8 *DiskName;
EFI_STRING_ID DiskNameId;
OPAL_DISK *OpalDisk;
HiiSetCurrentConfiguration();
gHiiConfiguration.SupportedDisks = 0;
for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {
OpalDisk = HiiGetOpalDiskCB (Index);
if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {
gHiiConfiguration.SupportedDisks |= (1 << Index);
DiskNameId = GetDiskNameStringId (Index);
DiskName = HiiDiskGetNameCB (Index);
if ((DiskName == NULL) || (DiskNameId == 0)) {
return EFI_UNSUPPORTED;
}
HiiSetFormString(DiskNameId, DiskName);
}
}
OpalHiiSetBrowserData ();
return EFI_SUCCESS;
}
/**
Get disk name string id.
@param DiskIndex The input disk index info.
@retval The disk name string id.
**/
EFI_STRING_ID
GetDiskNameStringId(
UINT8 DiskIndex
)
{
switch (DiskIndex) {
case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0);
case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1);
case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2);
case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3);
case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4);
case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5);
}
return 0;
}
/**
Confirm whether user truly want to do the revert action.
@param OpalDisk The device which need to do the revert action.
@retval EFI_SUCCESS Confirmed user want to do the revert action.
**/
EFI_STATUS
HiiConfirmRevertAction (
IN OPAL_DISK *OpalDisk
)
{
CHAR16 Unicode[512];
EFI_INPUT_KEY Key;
CHAR16 ApproveResponse;
CHAR16 RejectResponse;
//
// When the estimate cost time bigger than MAX_ACCEPTABLE_REVERTING_TIME, pop up dialog to let user confirm
// the revert action.
//
if (OpalDisk->EstimateTimeCost < MAX_ACCEPTABLE_REVERTING_TIME) {
return EFI_SUCCESS;
}
ApproveResponse = L'Y';
RejectResponse = L'N';
UnicodeSPrint(Unicode, StrSize(L"WARNING: Revert device needs about ####### seconds"), L"WARNING: Revert device needs about %d seconds", OpalDisk->EstimateTimeCost);
do {
CreatePopUp(
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
Unicode,
L" System should not be powered off until revert completion ",
L" ",
L" Press 'Y/y' to continue, press 'N/n' to cancal ",
NULL
);
} while (
((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (ApproveResponse | UPPER_LOWER_CASE_OFFSET)) &&
((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (RejectResponse | UPPER_LOWER_CASE_OFFSET))
);
if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (RejectResponse | UPPER_LOWER_CASE_OFFSET)) {
return EFI_ABORTED;
}
return EFI_SUCCESS;
}
/**
This function processes the results of changes in configuration.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser.
@param QuestionId A unique value which is sent to the original
exporting driver so that it can identify the type
of data to expect.
@param Type The type of value for the question.
@param Value A pointer to the data being sent to the original
exporting driver.
@param ActionRequest On return, points to the action requested by the
callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved.
@retval EFI_UNSUPPORTED The specified Action is not supported by the
callback.
**/
EFI_STATUS
EFIAPI
DriverCallback(
CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
EFI_BROWSER_ACTION Action,
EFI_QUESTION_ID QuestionId,
UINT8 Type,
EFI_IFR_TYPE_VALUE *Value,
EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
HII_KEY HiiKey;
UINT8 HiiKeyId;
UINT32 PpRequest;
OPAL_DISK *OpalDisk;
if (ActionRequest != NULL) {
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
} else {
return EFI_INVALID_PARAMETER;
}
//
// If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.
//
if ((QuestionId & HII_KEY_FLAG) == 0) {
return EFI_SUCCESS;
}
HiiKey.Raw = QuestionId;
HiiKeyId = (UINT8) HiiKey.KeyBits.Id;
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
switch (HiiKeyId) {
case HII_KEY_ID_VAR_SUPPORTED_DISKS:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
return HiiPopulateMainMenuForm ();
case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS\n"));
return HiiPopulateDiskInfoForm();
}
} else if (Action == EFI_BROWSER_ACTION_CHANGING) {
switch (HiiKeyId) {
case HII_KEY_ID_GOTO_DISK_INFO:
return HiiSelectDisk((UINT8)HiiKey.KeyBits.Index);
case HII_KEY_ID_REVERT:
case HII_KEY_ID_PSID_REVERT:
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
return HiiConfirmRevertAction (OpalDisk);
} else {
ASSERT (FALSE);
return EFI_SUCCESS;
}
}
} else if (Action == EFI_BROWSER_ACTION_CHANGED) {
switch (HiiKeyId) {
case HII_KEY_ID_BLOCKSID:
switch (Value->u8) {
case 0:
PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
break;
case 1:
PpRequest = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID;
break;
case 2:
PpRequest = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID;
break;
case 3:
PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE;
break;
case 4:
PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE;
break;
case 5:
PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE;
break;
case 6:
PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE;
break;
default:
PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
DEBUG ((DEBUG_ERROR, "Invalid value input!\n"));
break;
}
HiiSetBlockSidAction(PpRequest);
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
case HII_KEY_ID_SET_ADMIN_PWD:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_SET_ADMIN_PWD\n"));
gHiiConfiguration.OpalRequest.SetAdminPwd = Value->b;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
case HII_KEY_ID_SET_USER_PWD:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_SET_USER_PWD\n"));
gHiiConfiguration.OpalRequest.SetUserPwd = Value->b;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
case HII_KEY_ID_SECURE_ERASE:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_SECURE_ERASE\n"));
gHiiConfiguration.OpalRequest.SecureErase = Value->b;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
case HII_KEY_ID_REVERT:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_REVERT\n"));
gHiiConfiguration.OpalRequest.Revert = Value->b;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
case HII_KEY_ID_KEEP_USER_DATA:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_KEEP_USER_DATA\n"));
gHiiConfiguration.OpalRequest.KeepUserData = Value->b;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
case HII_KEY_ID_PSID_REVERT:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_PSID_REVERT\n"));
gHiiConfiguration.OpalRequest.PsidRevert = Value->b;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
case HII_KEY_ID_DISABLE_USER:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_DISABLE_USER\n"));
gHiiConfiguration.OpalRequest.DisableUser = Value->b;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
case HII_KEY_ID_ENABLE_FEATURE:
DEBUG ((DEBUG_INFO, "HII_KEY_ID_ENABLE_FEATURE\n"));
gHiiConfiguration.OpalRequest.EnableFeature = Value->b;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
return EFI_SUCCESS;
default:
break;
}
}
return EFI_UNSUPPORTED;
}
/**
Update the global Disk index info.
@param Index The input disk index info.
@retval EFI_SUCCESS Update the disk index info success.
**/
EFI_STATUS
HiiSelectDisk(
UINT8 Index
)
{
OpalHiiGetBrowserData();
gHiiConfiguration.SelectedDiskIndex = Index;
OpalHiiSetBrowserData ();
return EFI_SUCCESS;
}
/**
Draws the disk info form.
@retval EFI_SUCCESS Draw the disk info success.
**/
EFI_STATUS
HiiPopulateDiskInfoForm(
VOID
)
{
OPAL_DISK* OpalDisk;
OPAL_DISK_ACTIONS AvailActions;
TCG_RESULT Ret;
CHAR8 *DiskName;
OpalHiiGetBrowserData();
DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);
if (DiskName == NULL) {
return EFI_UNSUPPORTED;
}
HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);
gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;
ZeroMem (&gHiiConfiguration.OpalRequest, sizeof (OPAL_REQUEST));
gHiiConfiguration.KeepUserDataForced = FALSE;
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
if (OpalDisk != NULL) {
OpalDiskUpdateStatus (OpalDisk);
Ret = OpalSupportGetAvailableActions(&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);
if (Ret == TcgResultSuccess) {
//
// Update actions, always allow PSID Revert
//
gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;
//
// Always allow unlock to handle device migration
//
gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;
if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {
if (OpalDisk->Owner == OpalOwnershipNobody) {
gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;
//
// Update strings
//
HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");
} else {
DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));
}
} else {
gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;
gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;
gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;
gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;
gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;
HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");
//
// Determine revert options for disk
// Default initialize keep user Data to be true
//
gHiiConfiguration.OpalRequest.KeepUserData = 1;
if (AvailActions.RevertKeepDataForced) {
gHiiConfiguration.KeepUserDataForced = TRUE;
}
}
}
GetSavedOpalRequest (OpalDisk, &gHiiConfiguration.OpalRequest);
}
//
// Pass the current configuration to the BIOS
//
OpalHiiSetBrowserData ();
return EFI_SUCCESS;
}
/**
Send BlockSid request through TPM physical presence module.
@param PpRequest TPM physical presence operation request.
@retval EFI_SUCCESS Do the required action success.
@retval Others Other error occur.
**/
EFI_STATUS
HiiSetBlockSidAction (
IN UINT32 PpRequest
)
{
UINT32 ReturnCode;
EFI_STATUS Status;
ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);
if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
Status = EFI_SUCCESS;
} else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
Status = EFI_OUT_OF_RESOURCES;
} else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
Status = EFI_UNSUPPORTED;
} else {
Status = EFI_DEVICE_ERROR;
}
return Status;
}
/**
This function processes the results of changes in configuration.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Configuration A null-terminated Unicode string in <ConfigResp>
format.
@param Progress A pointer to a string filled in with the offset of
the most recent '&' before the first failing
name/value pair (or the beginning of the string if
the failure is in the first name/value pair) or
the terminating NULL if all was successful.
@retval EFI_SUCCESS The Results is processed successfully.
@retval EFI_INVALID_PARAMETER Configuration is NULL.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
driver.
**/
EFI_STATUS
EFIAPI
RouteConfig(
CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
CONST EFI_STRING Configuration,
EFI_STRING *Progress
)
{
if (Configuration == NULL || Progress == NULL) {
return (EFI_INVALID_PARAMETER);
}
*Progress = Configuration;
if (!HiiIsConfigHdrMatch (Configuration, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
return EFI_NOT_FOUND;
}
*Progress = Configuration + StrLen (Configuration);
return EFI_SUCCESS;
}
/**
This function allows a caller to extract the current configuration for one
or more named elements from the target driver.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Request A null-terminated Unicode string in
<ConfigRequest> format.
@param Progress On return, points to a character in the Request
string. Points to the string's null terminator if
request was successful. Points to the most recent
'&' before the first failing name/value pair (or
the beginning of the string if the failure is in
the first name/value pair) if the request was not
successful.
@param Results A null-terminated Unicode string in
<ConfigAltResp> format which has all values filled
in for the names in the Request string. String to
be allocated by the called function.
@retval EFI_SUCCESS The Results is filled with the requested values.
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
@retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
driver.
**/
EFI_STATUS
EFIAPI
ExtractConfig(
CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
CONST EFI_STRING Request,
EFI_STRING *Progress,
EFI_STRING *Results
)
{
EFI_STATUS Status;
EFI_STRING ConfigRequest;
EFI_STRING ConfigRequestHdr;
UINTN BufferSize;
UINTN Size;
BOOLEAN AllocatedRequest;
EFI_HANDLE DriverHandle;
//
// Check for valid parameters
//
if (Progress == NULL || Results == NULL) {
return (EFI_INVALID_PARAMETER);
}
*Progress = Request;
if ((Request != NULL) &&
!HiiIsConfigHdrMatch (Request, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
return EFI_NOT_FOUND;
}
AllocatedRequest = FALSE;
BufferSize = sizeof (OPAL_HII_CONFIGURATION);
ConfigRequest = Request;
if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
//
// Request has no request element, construct full request string.
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
//
DriverHandle = HiiGetDriverImageHandleCB();
ConfigRequestHdr = HiiConstructConfigHdr (&gHiiSetupVariableGuid, OpalPasswordStorageName, DriverHandle);
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
ConfigRequest = AllocateZeroPool (Size);
if (ConfigRequest == NULL) {
return EFI_OUT_OF_RESOURCES;
}
AllocatedRequest = TRUE;
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
FreePool (ConfigRequestHdr);
}
//
// Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )
//
Status = gHiiConfigRouting->BlockToConfig(
gHiiConfigRouting,
ConfigRequest,
(UINT8*)&gHiiConfiguration,
sizeof(OPAL_HII_CONFIGURATION),
Results,
Progress
);
//
// Free the allocated config request string.
//
if (AllocatedRequest) {
FreePool (ConfigRequest);
ConfigRequest = NULL;
}
//
// Set Progress string to the original request string.
//
if (Request == NULL) {
*Progress = NULL;
} else if (StrStr (Request, L"OFFSET") == NULL) {
*Progress = Request + StrLen (Request);
}
return (Status);
}
/**
Pass the current system state to the bios via the hii_G_Configuration.
**/
VOID
OpalHiiSetBrowserData (
VOID
)
{
HiiSetBrowserData(
&gHiiSetupVariableGuid,
(CHAR16*)L"OpalHiiConfig",
sizeof(gHiiConfiguration),
(UINT8*)&gHiiConfiguration,
NULL
);
}
/**
Populate the hii_g_Configuraton with the browser Data.
**/
VOID
OpalHiiGetBrowserData (
VOID
)
{
HiiGetBrowserData(
&gHiiSetupVariableGuid,
(CHAR16*)L"OpalHiiConfig",
sizeof(gHiiConfiguration),
(UINT8*)&gHiiConfiguration
);
}
/**
Set a string Value in a form.
@param DestStringId The stringid which need to update.
@param SrcAsciiStr The string nned to update.
@retval EFI_SUCCESS Do the required action success.
@retval Others Other error occur.
**/
EFI_STATUS
HiiSetFormString(
EFI_STRING_ID DestStringId,
CHAR8 *SrcAsciiStr
)
{
UINT32 Len;
UINT32 UniSize;
CHAR16* UniStr;
//
// Determine the Length of the sting
//
Len = ( UINT32 )AsciiStrLen( SrcAsciiStr );
//
// Allocate space for the unicode string, including terminator
//
UniSize = (Len + 1) * sizeof(CHAR16);
UniStr = (CHAR16*)AllocateZeroPool(UniSize);
//
// Copy into unicode string, then copy into string id
//
AsciiStrToUnicodeStrS ( SrcAsciiStr, UniStr, Len + 1);
//
// Update the string in the form
//
if (HiiSetString(gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {
DEBUG ((DEBUG_INFO, "HiiSetFormString( ) failed\n"));
FreePool(UniStr);
return (EFI_OUT_OF_RESOURCES);
}
//
// Free the memory
//
FreePool(UniStr);
return (EFI_SUCCESS);
}
/**
Initialize the Opal disk base on the hardware info get from device.
@param Dev The Opal device.
@retval EFI_SUCESS Initialize the device success.
@retval EFI_DEVICE_ERROR Get info from device failed.
**/
EFI_STATUS
OpalDiskInitialize (
IN OPAL_DRIVER_DEVICE *Dev
)
{
TCG_RESULT TcgResult;
OPAL_SESSION Session;
UINT8 ActiveDataRemovalMechanism;
UINT32 RemovalMechanishLists[ResearvedMechanism];
ZeroMem(&Dev->OpalDisk, sizeof(OPAL_DISK));
Dev->OpalDisk.Sscp = Dev->Sscp;
Dev->OpalDisk.MediaId = Dev->MediaId;
Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;
ZeroMem(&Session, sizeof(Session));
Session.Sscp = Dev->Sscp;
Session.MediaId = Dev->MediaId;
TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);
if (TcgResult != TcgResultSuccess) {
return EFI_DEVICE_ERROR;
}
Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGHT, &Dev->OpalDisk.MsidLength);
if (TcgResult != TcgResultSuccess) {
return EFI_DEVICE_ERROR;
}
if (Dev->OpalDisk.SupportedAttributes.DataRemoval) {
TcgResult = OpalUtilGetDataRemovalMechanismLists (&Session, RemovalMechanishLists);
if (TcgResult != TcgResultSuccess) {
return EFI_DEVICE_ERROR;
}
TcgResult = OpalUtilGetActiveDataRemovalMechanism (&Session, Dev->OpalDisk.Msid, Dev->OpalDisk.MsidLength, &ActiveDataRemovalMechanism);
if (TcgResult != TcgResultSuccess) {
return EFI_DEVICE_ERROR;
}
Dev->OpalDisk.EstimateTimeCost = RemovalMechanishLists[ActiveDataRemovalMechanism];
}
return OpalDiskUpdateStatus (&Dev->OpalDisk);
}
/**
Update the device info.
@param OpalDisk The Opal device.
@retval EFI_SUCESS Initialize the device success.
@retval EFI_DEVICE_ERROR Get info from device failed.
@retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.
**/
EFI_STATUS
OpalDiskUpdateStatus (
OPAL_DISK *OpalDisk
)
{
TCG_RESULT TcgResult;
OPAL_SESSION Session;
ZeroMem(&Session, sizeof(Session));
Session.Sscp = OpalDisk->Sscp;
Session.MediaId = OpalDisk->MediaId;
Session.OpalBaseComId = OpalDisk->OpalBaseComId;
TcgResult = OpalGetLockingInfo(&Session, &OpalDisk->LockingFeature);
if (TcgResult != TcgResultSuccess) {
return EFI_DEVICE_ERROR;
}
if (OpalDisk->MsidLength == 0) {
return EFI_INVALID_PARAMETER;
} else {
//
// Base on the Msid info to get the ownership, so Msid info must get first.
//
OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength);
}
return EFI_SUCCESS;
}