alder_lake_bios/Intel/AlderLake/AlderLakePlatSamplePkg/Features/Amt/AmtWrapperDxe/AmtWrapperDxe.c

777 lines
19 KiB
C

/** @file
;******************************************************************************
;* Copyright 2021 Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corp.
;*
;******************************************************************************
*/
/**@file
AMT Wrapper Implementation.
@copyright
INTEL CONFIDENTIAL
Copyright 2009 - 2021 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include "AmtWrapperDxe.h"
#define CHAR_DATA_LINK_ESCAPE 0x10
#define NUMBER_OF_HOTKEY_CTRL_P 5
GLOBAL_REMOVE_IF_UNREFERENCED AMT_WRAPPER_PROTOCOL mAmtWrapperInstance = {
AmtWrapperGetSolDevicePath,
AmtWrapperSet,
AmtWrapperBootOptionExist,
AmtWrapperEnableStorageRedir,
AmtWrapperEnterSetup,
AmtWrapperPauseBoot,
AmtWrapperEnableKvm,
AmtWrapperEnableSecureErase,
AmtWrapperConsoleLocked,
AmtWrapperEnableSol,
AmtWrapperBdsBootViaAsf,
AmtWrapperGetNextAmtSetupPrompt,
AmtWrapperDetermineSetupHotKey,
AmtWrapperGetSupportedHotkeys,
AmtWrapperIsRemotePlatformEraseEnabled
};
GLOBAL_REMOVE_IF_UNREFERENCED UINTN mEnterRemoteAssistance = 0;
GLOBAL_REMOVE_IF_UNREFERENCED UINTN mEnterMebxSetup = 0;
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mFwImageType;
GLOBAL_REMOVE_IF_UNREFERENCED PLATFORM_PCI_SERIAL_OVER_LAN_DEVICE_PATH mSerialOverLanDevicePath = {
gPciRootBridge,
{
{
HARDWARE_DEVICE_PATH,
HW_PCI_DP,
{
(UINT8)(sizeof (PCI_DEVICE_PATH)),
(UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
}
},
SOL_FUNCTION_NUMBER,
ME_DEVICE_NUMBER
},
{
{
MESSAGING_DEVICE_PATH,
MSG_UART_DP,
{
(UINT8)(sizeof (UART_DEVICE_PATH)),
(UINT8)((sizeof (UART_DEVICE_PATH)) >> 8)
}
},
0,
115200,
8,
1,
1
},
{
{
MESSAGING_DEVICE_PATH,
MSG_VENDOR_DP,
{
(UINT8)(sizeof (VENDOR_DEVICE_PATH)),
(UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
}
},
DEVICE_PATH_MESSAGING_PC_ANSI
},
gEndEntire
};
//
// Function implementations
//
/**
Check if USB-R port for remote session is enabled in runtime.
@retval TRUE USB-R Port for Remote Console is Enabled.
@retval FALSE USB-R Port for Remote Console is NOT Enabled.
**/
BOOLEAN
STATIC
IsRemoteUsbrPortEnabled (
VOID
)
{
UINT64 XhciPciMmBase;
UINT64 XhciMmioBase;
UINT64 UsbrMmioBase;
UINT8 OrgCmd;
BOOLEAN IsPortEnabled;
IsPortEnabled = FALSE;
XhciPciMmBase = PchXhciPciCfgBase ();
if (PciSegmentRead32 (XhciPciMmBase + PCI_VENDOR_ID_OFFSET) == 0xFFFFFFFF) {
return IsPortEnabled;
}
OrgCmd = PciSegmentRead8 (XhciPciMmBase + PCI_COMMAND_OFFSET);
XhciMmioBase = PciSegmentRead32 (XhciPciMmBase + PCI_BASE_ADDRESSREG_OFFSET) & ~(UINT32)B_XHCI_CFG_ALIGN_MASK;
if ((PciSegmentRead32 (XhciPciMmBase + PCI_BASE_ADDRESSREG_OFFSET) & B_PCI_BAR_MEMORY_TYPE_MASK) == B_PCI_BAR_MEMORY_TYPE_64) {
XhciMmioBase += LShiftU64((UINT64)PciSegmentRead32 (XhciPciMmBase + (PCI_BASE_ADDRESSREG_OFFSET + 4)), 32);
}
if (XhciMmioBase == 0) {
return IsPortEnabled;
}
if ((OrgCmd & EFI_PCI_COMMAND_MEMORY_SPACE) == 0) {
PciSegmentWrite8 (XhciPciMmBase + PCI_COMMAND_OFFSET, OrgCmd | EFI_PCI_COMMAND_MEMORY_SPACE);
}
//
// Check if KVM Port is Enabled and Connected
//
UsbrMmioBase = XhciMmioBase + R_XHCI_MEM_PORTSC_START_OFFSET + (GetPchUsbrKvmPortNum () * S_XHCI_MEM_PORTSC_PORT_SPACING);
if ((MmioRead32 (UsbrMmioBase) & (B_XHCI_MEM_PORTSCXUSB2_PED | B_XHCI_MEM_PORTSCXUSB2_CCS)) == (B_XHCI_MEM_PORTSCXUSB2_PED | B_XHCI_MEM_PORTSCXUSB2_CCS)) {
IsPortEnabled = TRUE;
}
if ((OrgCmd & EFI_PCI_COMMAND_MEMORY_SPACE) == 0) {
PciSegmentWrite8 (XhciPciMmBase + PCI_COMMAND_OFFSET, OrgCmd);
}
DEBUG ((DEBUG_INFO, "IsPortEnabled = %x\n", IsPortEnabled));
return IsPortEnabled;
}
BOOLEAN
IsCtrlKey (
IN UINT32 KeyShiftState
)
{
if ((KeyShiftState & EFI_SHIFT_STATE_VALID) && (KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED))) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsAltKey (
IN UINT32 KeyShiftState
)
{
if ((KeyShiftState & EFI_SHIFT_STATE_VALID) && (KeyShiftState & (EFI_RIGHT_ALT_PRESSED | EFI_LEFT_ALT_PRESSED))) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPKey (
IN CHAR16 UnicodeChar
)
{
if (UnicodeChar == L'p' || UnicodeChar == L'P') {
return TRUE;
} else {
return FALSE;
}
}
/**
Update AMT DXE config block to enter MEBX.
**/
VOID
EnterMebxSetup (
VOID
)
{
EFI_STATUS Status;
AMT_POLICY_PROTOCOL *AmtPolicy;
AMT_DXE_CONFIG *AmtDxeConfig;
Status = gBS->LocateProtocol (&gDxeAmtPolicyGuid, NULL, (VOID **) &AmtPolicy);
if (!EFI_ERROR (Status)) {
Status = GetConfigBlock ((VOID *) AmtPolicy, &gAmtDxeConfigGuid, (VOID *) &AmtDxeConfig);
ASSERT_EFI_ERROR (Status);
AmtDxeConfig->AmtbxHotkeyPressed = 1;
AmtDxeConfig->CiraRequest = 0;
}
DEBUG ((DEBUG_INFO, "Entering MEBX Setup\n"));
}
/**
Update AMT DXE config block to enter remote assistance.
**/
VOID
EnterRemoteAssistance (
VOID
)
{
EFI_STATUS Status;
AMT_POLICY_PROTOCOL *AmtPolicy;
AMT_DXE_CONFIG *AmtDxeConfig;
Status = gBS->LocateProtocol (&gDxeAmtPolicyGuid, NULL, (VOID **) &AmtPolicy);
if (!EFI_ERROR (Status)) {
Status = GetConfigBlock ((VOID *) AmtPolicy, &gAmtDxeConfigGuid, (VOID *) &AmtDxeConfig);
ASSERT_EFI_ERROR (Status);
AmtDxeConfig->AmtbxHotkeyPressed = 1;
AmtDxeConfig->CiraRequest = 1;
}
DEBUG ((DEBUG_INFO, "Entering Remote Assistance\n"));
}
/**
Check if Remote Assistance Prompt can be displayed.
@retval TRUE Display Remote Assistance Prompt.
@retval FALSE Do not display Remote Assistance Prompt.
**/
BOOLEAN
DisplayRemoteAssistancePrompt (
VOID
)
{
EFI_STATUS Status;
AMT_POLICY_PROTOCOL *AmtPolicy;
AMT_DXE_CONFIG *AmtDxeConfig;
Status = gBS->LocateProtocol (&gDxeAmtPolicyGuid, NULL, (VOID **) &AmtPolicy);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Locate AmtPolicy fail, remote Assistance not supported\n"));
return FALSE;
}
Status = GetConfigBlock ((VOID *) AmtPolicy, &gAmtDxeConfigGuid, (VOID *) &AmtDxeConfig);
ASSERT_EFI_ERROR (Status);
if (AmtDxeConfig->AmtbxSelectionScreen == 1) {
return FALSE;
}
return IsCiraAvailable ();
}
/**
Check if BIOS hot key can be enabled.
@retval True BIOS hot key can be enabled.
@retval False BIOS hot key can not be enabled.
**/
BOOLEAN
IsBiosHotkeyEnabled (
VOID
)
{
EFI_STATUS Status;
HECI_PROTOCOL *Heci;
UINT32 MeMode;
Heci = NULL;
MeMode = ME_MODE_TEMP_DISABLED;
Status = gBS->LocateProtocol (&gHeciProtocolGuid, NULL, (VOID **) &Heci);
if (EFI_ERROR (Status)) {
return FALSE;
}
Status = Heci->GetMeMode (&MeMode);
if (EFI_ERROR (Status)) {
return FALSE;
}
if ((mFwImageType != IntelMeConsumerFw) && (MeMode == ME_MODE_NORMAL)) {
return TRUE;
}
return FALSE;
}
/**
Checks if Manageability is supported.
@retval True Manageability is supported.
@retval False Manageability is not supported.
**/
BOOLEAN
IsManageabilitySupported (
VOID
)
{
ME_BIOS_PAYLOAD_HOB *MbpHob;
MbpHob = GetFirstGuidHob (&gMeBiosPayloadHobGuid);
if (MbpHob == NULL) {
DEBUG ((DEBUG_ERROR, "No MBP Data Protocol available\n"));
return FALSE;
}
if (MbpHob->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.Amt == 0) {
return FALSE;
}
return TRUE;
}
/**
Get AMT Setup Promt String.
@param[out] String Setup promt string.
@retval EFI_SUCCESS Get Setup Promt String successfully.
@retval EFI_NOT_FOUND Setup Promt String is not found.
@retval EFI_UNSUPPORTED Get Setup Promt String is not supported.
@retval EFI_INVALID_PARAMETER One of parameters is NULL.
**/
EFI_STATUS
EFIAPI
AmtWrapperGetNextAmtSetupPrompt (
OUT CHAR16 **String
)
{
STATIC UINTN PromptIndex = 0;
UINTN StringCounts;
EFI_STRING SetupPrompt[] = {
L"Press [CTRL+ALT+F1] to enter MEBx Remote Assistance."
};
if (String == NULL) {
return EFI_INVALID_PARAMETER;
}
*String = NULL;
if (AsfIsSolEnabled () || AsfIsKvmEnabled () || !IsBiosHotkeyEnabled () || !IsManageabilitySupported ()) {
//
// Skip setup prompt if ASF SOL or KVM enabled.
//
return EFI_UNSUPPORTED;
}
StringCounts = DisplayRemoteAssistancePrompt ()? sizeof (SetupPrompt) / sizeof (EFI_STRING) : sizeof (SetupPrompt) / sizeof (EFI_STRING) - 1;
if (PromptIndex < StringCounts) {
*String = SetupPrompt [PromptIndex];
PromptIndex++;
return EFI_SUCCESS;
} else {
PromptIndex = 0;
return EFI_NOT_FOUND;
}
}
/**
Determine if AMT hot key is pressed.
Ctrl+ALT+F1 : Scan = 0x0B, Shift = 0x3C
Ctrl+P : Unicode = 0x10/L'p', Shift = 0x0C
@param[in] KeyData Hot Key Data.
@retval EFI_SUCCESS AMT hot key is pressed.
@retval EFI_NOT_FOUND AMT hot key is not pressed.
**/
EFI_STATUS
EFIAPI
AmtWrapperDetermineSetupHotKey (
IN EFI_KEY_DATA *KeyData
)
{
//
// React to hotkey once per boot only
//
if (mEnterMebxSetup || mEnterRemoteAssistance) {
return EFI_NOT_FOUND;
}
if (AsfIsSolEnabled () || AsfIsKvmEnabled () || !IsBiosHotkeyEnabled () || !IsManageabilitySupported ()) {
//
// Skip AMT hot key check if ASF SOL or KVM enabled.
//
return EFI_NOT_FOUND;
}
DEBUG ((DEBUG_INFO, "<Scan=0x%X><Unicode=0x%X>\n", KeyData->Key.ScanCode, KeyData->Key.UnicodeChar));
DEBUG ((DEBUG_INFO, "<ShiftState=0x%X><ToggleState=0x%X>\n", KeyData->KeyState.KeyShiftState, KeyData->KeyState.KeyToggleState));
if ((DisplayRemoteAssistancePrompt () == TRUE) &&
(KeyData->Key.ScanCode == SCAN_F1) &&
IsCtrlKey (KeyData->KeyState.KeyShiftState) &&
IsAltKey (KeyData->KeyState.KeyShiftState)) {
EnterRemoteAssistance ();
mEnterRemoteAssistance = 1;
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
/**
Get Supported Hot Keys.
@param[out] KeyCnt Supported Hot Key Count.
@param[out] KeyData Supported Hot Key Data.
@retval EFI_SUCCESS Get Supported Hot Keys Successfully.
@retval EFI_OUT_OF_RESOURCES Out of memory.
@retval EFI_NOT_FOUND No Supported Hot Keys.
**/
EFI_STATUS
EFIAPI
AmtWrapperGetSupportedHotkeys (
OUT UINTN *KeyCnt,
OUT EFI_KEY_DATA **KeyData
)
{
EFI_KEY_DATA MeHotKeyTables[] = {
//
// Ctrl + Alt + F1
//
{ {SCAN_F1, CHAR_NULL}, {EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED | EFI_RIGHT_ALT_PRESSED, 0} },
{ {SCAN_F1, CHAR_NULL}, {EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_ALT_PRESSED, 0} },
{ {SCAN_F1, CHAR_NULL}, {EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_ALT_PRESSED, 0} },
{ {SCAN_F1, CHAR_NULL}, {EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_LEFT_ALT_PRESSED, 0} }
};
*KeyCnt = 0;
*KeyData = NULL;
if (IsBiosHotkeyEnabled () && !AmtWrapperConsoleLocked () && IsManageabilitySupported ()) {
if (DisplayRemoteAssistancePrompt ()) {
//
// CTRL + P and CTRL + ALT + F1 hotkey
//
*KeyCnt = sizeof (MeHotKeyTables) / sizeof (MeHotKeyTables[0]);
} else {
return EFI_NOT_FOUND;
}
*KeyData = AllocateZeroPool (sizeof (EFI_KEY_DATA) * (*KeyCnt));
if (*KeyData == NULL){
return EFI_OUT_OF_RESOURCES;
}
CopyMem (*KeyData, MeHotKeyTables, sizeof (EFI_KEY_DATA) * (*KeyCnt));
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
VOID
EFIAPI
AsfWatchDogStopOnSetupEntry (
IN EFI_EVENT Event,
IN VOID *Context
)
{
AmtWrapperSet (SET_WDT_STOP);
}
/**
Entry point for the Active Management Driver.
@param[in] ImageHandle Image handle of this driver.
@param[in] SystemTable Global system service table.
@retval EFI_SUCCESS Initialization complete.
@retval EFI_UNSUPPORTED The chipset is unsupported by this driver.
@retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
@retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
**/
EFI_STATUS
EFIAPI
AmtWrapperDxeEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
ME_BIOS_PAYLOAD_HOB *MbpHob;
EFI_EVENT PlatformSetupEvent;
VOID *Registration;
MbpHob = NULL;
mFwImageType = IntelMeConsumerFw;
//[-start-210421-IB09480139-remove]//
// ManageSecureBootState ();
//[-end-210421-IB09480139-remove]//
//
// Get Mbp Protocol
//
MbpHob = GetFirstGuidHob (&gMeBiosPayloadHobGuid);
if (MbpHob != NULL) {
mFwImageType = (UINT8)MbpHob->MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType;
}
//
// Install the AMT_WRAPPER_PROTOCOL interface
//
Status = gBS->InstallMultipleProtocolInterfaces (
&ImageHandle,
&gAmtWrapperProtocolGuid,
&mAmtWrapperInstance,
NULL
);
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
AsfWatchDogStopOnSetupEntry,
NULL,
&PlatformSetupEvent
);
ASSERT_EFI_ERROR (Status);
Status = gBS->RegisterProtocolNotify (
&gSetupEnterGuid,
PlatformSetupEvent,
&Registration
);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
Check if ASF boot options is present.
@retval True ASF boot option is present.
@retval False ASF boot option is not present
**/
BOOLEAN
EFIAPI
AmtWrapperBootOptionExist (
VOID
)
{
return AsfIsBootOptionsPresent ();
}
/**
Get Serial Over Lan Device Path
@param[in, out] DevicePath Device Path of Serial Over Lan
@retval True Get SOL Device Path Successful.
**/
BOOLEAN
EFIAPI
AmtWrapperGetSolDevicePath (
IN OUT VOID *DevicePath
)
{
*((PLATFORM_PCI_SERIAL_OVER_LAN_DEVICE_PATH **)DevicePath) = &mSerialOverLanDevicePath;
return TRUE;
}
/**
Setting for AMT wrapper
@param[in] Index Setting index
@retval True Required setting is supported.
@retval False Required setting is not supported.
**/
BOOLEAN
EFIAPI
AmtWrapperSet (
IN UINTN Index
)
{
EFI_HOB_GUID_TYPE *GuidHob;
AMT_PEI_CONFIG *AmtPeiConfig;
GuidHob = GetFirstGuidHob (&gAmtPolicyHobGuid);
if (GuidHob == NULL) {
return FALSE;
}
AmtPeiConfig = (AMT_PEI_CONFIG *) GET_GUID_HOB_DATA (GuidHob);
if (AmtPeiConfig->WatchDogEnabled == 0) {
return FALSE;
}
if (Index == SET_BIOS_WDT_START) {
AsfStartWatchDog (ASF_START_BIOS_WDT);
return TRUE;
} else if (Index == SET_OS_WDT_START) {
AsfStartWatchDog (ASF_START_OS_WDT);
return TRUE;
} else if (Index == SET_WDT_STOP) {
AsfStopWatchDog ();
return TRUE;
}
return FALSE;
}
/**
This will return Console Lock Boot Option.
True if the option is enabled.
@retval True Console Lock is enabled.
@retval False Console Lock is disabled.
**/
BOOLEAN
EFIAPI
AmtWrapperConsoleLocked (
VOID
)
{
return AsfIsConsoleLocked ();
}
/**
This will return Secure Erase Boot Option.
True if the option is enabled.
@retval True Secure Erase is enabled.
@retval False Secure Erase is disabled.
**/
BOOLEAN
EFIAPI
AmtWrapperEnableSecureErase (
VOID
)
{
return AsfIsSecureEraseEnabled ();
}
/**
This will return Serial-over-Lan Boot Option.
True if the option is enabled.
@retval True Serial-over-Lan is enabled.
@retval False Serial-over-Lan is disabled.
**/
BOOLEAN
EFIAPI
AmtWrapperEnableSol (
VOID
)
{
return AsfIsSolEnabled ();
}
/**
This will return Storage Redirection Boot Option.
True if the option is enabled.
@retval True Storage Redirection boot option is enabled.
@retval False Storage Redirection boot option is disabled.
**/
BOOLEAN
EFIAPI
AmtWrapperEnableStorageRedir (
VOID
)
{
return AsfIsStorageRedirectionEnabled ();
}
/**
This will return BIOS Pause Boot Option.
True if the option is enabled.
@retval True BIOS Pause is enabled.
@retval False BIOS Pause is disabled.
**/
BOOLEAN
EFIAPI
AmtWrapperPauseBoot (
VOID
)
{
return AsfIsPauseBootEnabled ();
}
/**
This will return BIOS Setup Boot Option.
True if the option is enabled.
@retval True BIOS Setup is enabled.
@retval False BIOS Setup is disabled.
**/
BOOLEAN
EFIAPI
AmtWrapperEnterSetup (
VOID
)
{
return AsfIsEnterSetupEnabled ();
}
/**
Process ASF boot options and if available, attempt the boot
@retval EFI_SUCCESS The command completed successfully
**/
EFI_STATUS
EFIAPI
AmtWrapperBdsBootViaAsf (
VOID
)
{
return BdsBootViaAsf ();
}
/**
This will return KVM Boot Option.
True if the option is enabled.
@retval True KVM is enabled.
@retval False KVM is disabled.
**/
BOOLEAN
EFIAPI
AmtWrapperEnableKvm (
VOID
)
{
return AsfIsKvmEnabled () || IsRemoteUsbrPortEnabled ();
}
/**
This will return Remote Platform Erase Boot Option.
@retval True Remote Platform Erase is enabled.
@retval False Remote Platform Erase is disabled.
**/
BOOLEAN
EFIAPI
AmtWrapperIsRemotePlatformEraseEnabled (
VOID
)
{
return AsfIsRemotePlatformEraseEnabled ();
}