REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4735 When change callback action from FORM_OPEN to RETRIEVE, it is observed that NVNE disks will not be displayed when the user enters the formset at the first time. Revisit the formset can see the update. 1. Add HiiUpdateForm() to force reparsing the IFR binary when RETRIEVE. 2. Create dummy label with suppressif statement in VFR for form update usage. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Dandan Bi <dandan.bi@intel.com> Cc: Ming Tan <ming.tan@intel.com> Cc: Arthur Chen <arthur.g.chen@intel.com> Cc: Xiao X Chen <xiao.x.chen@intel.com> Cc: Tina Chen <tina.chen@intel.com> Signed-off-by: CindyX Kuo <cindyx.kuo@intel.com> Reviewed-by: Dandan Bi <dandan.bi@intel.com> Reviewed-by: Tina Chen <tina.chen@intel.com> Acked-by: Jiewen Yao <jiewen.yao@intel.com>
1368 lines
43 KiB
C
1368 lines
43 KiB
C
/** @file
|
|
Implementation of the HII for the Opal UEFI Driver.
|
|
|
|
Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#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;
|
|
const EFI_GUID gOpalSetupFormSetGuid = SETUP_FORMSET_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", __func__));
|
|
|
|
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", __func__));
|
|
}
|
|
|
|
/**
|
|
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", __func__));
|
|
|
|
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", __func__));
|
|
}
|
|
|
|
/**
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
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 perform data removal action.
|
|
@param ActionString Specifies the action name shown on pop up menu.
|
|
|
|
@retval EFI_SUCCESS Confirmed user want to do the revert action.
|
|
**/
|
|
EFI_STATUS
|
|
HiiConfirmDataRemovalAction (
|
|
IN OPAL_DISK *OpalDisk,
|
|
IN CHAR16 *ActionString
|
|
|
|
)
|
|
{
|
|
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: ############# action needs about ####### seconds"), L"WARNING: %s action needs about %d seconds", ActionString, OpalDisk->EstimateTimeCost);
|
|
|
|
do {
|
|
CreatePopUp (
|
|
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
|
&Key,
|
|
Unicode,
|
|
L" System should not be powered off until action completion ",
|
|
L" ",
|
|
L" Press 'Y/y' to continue, press 'N/n' to cancel ",
|
|
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;
|
|
EFI_STATUS Status;
|
|
VOID *StartOpCodeHandle;
|
|
VOID *EndOpCodeHandle;
|
|
EFI_IFR_GUID_LABEL *StartLabel;
|
|
EFI_IFR_GUID_LABEL *EndLabel;
|
|
|
|
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_RETRIEVE) {
|
|
if ((HiiKeyId == HII_KEY_ID_VAR_SUPPORTED_DISKS) || (HiiKeyId == HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS)) {
|
|
//
|
|
// Allocate space for creation of UpdateData Buffer
|
|
//
|
|
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
if (StartOpCodeHandle == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
EndOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
if (EndOpCodeHandle == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Create Hii Extend Label OpCode as the start opcode
|
|
//
|
|
StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
|
|
//
|
|
// Create Hii Extend Label OpCode as the end opcode
|
|
//
|
|
EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
|
|
switch (HiiKeyId) {
|
|
case HII_KEY_ID_VAR_SUPPORTED_DISKS:
|
|
DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
|
|
Status = HiiPopulateMainMenuForm ();
|
|
|
|
StartLabel->Number = OPAL_MAIN_MENU_LABEL_START;
|
|
EndLabel->Number = OPAL_MAIN_MENU_LABEL_END;
|
|
HiiUpdateForm (
|
|
gHiiPackageListHandle,
|
|
(EFI_GUID *)&gOpalSetupFormSetGuid,
|
|
FORMID_VALUE_MAIN_MENU,
|
|
StartOpCodeHandle,
|
|
EndOpCodeHandle
|
|
);
|
|
break;
|
|
|
|
case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:
|
|
DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS\n"));
|
|
Status = HiiPopulateDiskInfoForm ();
|
|
|
|
StartLabel->Number = OPAL_DISK_INFO_LABEL_START;
|
|
EndLabel->Number = OPAL_DISK_INFO_LABEL_END;
|
|
HiiUpdateForm (
|
|
gHiiPackageListHandle,
|
|
(EFI_GUID *)&gOpalSetupFormSetGuid,
|
|
FORMID_VALUE_DISK_INFO_FORM_MAIN,
|
|
StartOpCodeHandle,
|
|
EndOpCodeHandle
|
|
);
|
|
break;
|
|
}
|
|
|
|
HiiFreeOpCodeHandle (StartOpCodeHandle);
|
|
HiiFreeOpCodeHandle (EndOpCodeHandle);
|
|
|
|
return Status;
|
|
}
|
|
} 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 HiiConfirmDataRemovalAction (OpalDisk, L"Revert");
|
|
} else {
|
|
ASSERT (FALSE);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
case HII_KEY_ID_SECURE_ERASE:
|
|
OpalDisk = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
|
|
if (OpalDisk != NULL) {
|
|
return HiiConfirmDataRemovalAction (OpalDisk, L"Secure erase");
|
|
} 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_Configuration 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 need 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_SUCCESS 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_LENGTH, &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 ownship
|
|
|
|
@param OpalDisk The Opal device.
|
|
|
|
@retval EFI_SUCCESS Get ownership success.
|
|
@retval EFI_ACCESS_DENIED Has send BlockSID command, can't change ownership.
|
|
@retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
OpalDiskUpdateOwnerShip (
|
|
OPAL_DISK *OpalDisk
|
|
)
|
|
{
|
|
OPAL_SESSION Session;
|
|
|
|
if (OpalDisk->MsidLength == 0) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (OpalDisk->SentBlockSID) {
|
|
return EFI_ACCESS_DENIED;
|
|
}
|
|
|
|
ZeroMem (&Session, sizeof (Session));
|
|
Session.Sscp = OpalDisk->Sscp;
|
|
Session.MediaId = OpalDisk->MediaId;
|
|
Session.OpalBaseComId = OpalDisk->OpalBaseComId;
|
|
|
|
OpalDisk->Owner = OpalUtilDetermineOwnership (&Session, OpalDisk->Msid, OpalDisk->MsidLength);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Update the device info.
|
|
|
|
@param OpalDisk The Opal device.
|
|
|
|
@retval EFI_SUCCESS 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.
|
|
@retval EFI_ACCESS_DENIED Has send BlockSID command, can't change ownership.
|
|
|
|
**/
|
|
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;
|
|
}
|
|
|
|
return OpalDiskUpdateOwnerShip (OpalDisk);
|
|
}
|