245 lines
7.4 KiB
C
245 lines
7.4 KiB
C
/**@file
|
|
Send AMT MAC PassThrough Command.
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2020 - 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 <SetupVariable.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/DxeAmtHeciLib.h>
|
|
#include <Library/HobLib.h>
|
|
#include <Library/PciSegmentLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <MeBiosPayloadHob.h>
|
|
#include <Uefi.h>
|
|
#include <Register/HeciRegs.h>
|
|
#include <Register/MeRegs.h>
|
|
#include <Protocol/Spi.h>
|
|
|
|
#define MAC_PASS_THRU_VAR L"MacPassThrough"
|
|
typedef struct {
|
|
UINT8 MacPassThrough;
|
|
UINT8 MacBuffer[MAC_ADDRESS_SIZE];
|
|
} MAC_PASS_THRU_CONFIG;
|
|
|
|
/**
|
|
Get mac address from Gbe region
|
|
|
|
@param[out] MacBuffer Buffer for the MAC, if return error, buffers value won't be change.
|
|
|
|
@retval EFI_SUCCESS successful
|
|
@retval Other Vals something wrong
|
|
|
|
**/
|
|
EFI_STATUS
|
|
AmtGetGbeMac (
|
|
OUT UINT8 *MacBuffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PCH_SPI_PROTOCOL *SpiProtocol;
|
|
UINT32 *TmpPtr;
|
|
UINT8 TempBuffer[MAC_ADDRESS_SIZE];
|
|
UINT8 Index;
|
|
|
|
if (MacBuffer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
//
|
|
// Locate the SPI protocol.
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&gPchSpiProtocolGuid,
|
|
NULL,
|
|
(VOID **) &SpiProtocol
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
//
|
|
// Read MAC address from GbE region
|
|
//
|
|
Status = SpiProtocol->FlashRead (
|
|
SpiProtocol,
|
|
FlashRegionGbE,
|
|
(UINT32)0,
|
|
(UINT32)MAC_ADDRESS_SIZE,
|
|
TempBuffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
TmpPtr = (UINT32 *) TempBuffer;
|
|
if (((*TmpPtr & 0x00FFFFFF) == 0x00888888) || ((*TmpPtr & 0x00FFFFFF) == 0x00000000) || ((*TmpPtr & 0x00FFFFFF) == 0x00FFFFFF)) {
|
|
// Invalid according to OUI/MA-L list from IEEE
|
|
DEBUG ((DEBUG_INFO, "AMT GbE MAC: first 24 bits are invalid - %06x\n", (*TmpPtr & 0x00FFFFFF)));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
for (Index = 0; Index < MAC_ADDRESS_SIZE; Index++) {
|
|
MacBuffer[Index] = TempBuffer[Index];
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
This event will send MAC assresss into CSME
|
|
|
|
@param[in] Event - A pointer to the Event that triggered the callback.
|
|
@param[in] Context - A pointer to private data registered with the callback function.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
AmtSendMacAddress (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
ME_SETUP MeSetup;
|
|
UINTN DataSize;
|
|
//
|
|
// Initialization MAC default address.
|
|
//
|
|
UINT8 MacBuffer[MAC_ADDRESS_SIZE] = {0x88,0x88,0x88,0x88,0x87,0x88};
|
|
MAC_PASS_THRU_CONFIG MacConfig;
|
|
UINT32 Attributes;
|
|
|
|
DataSize = sizeof (ME_SETUP);
|
|
Status = gRT->GetVariable (L"MeSetup", &gMeSetupVariableGuid, NULL, &DataSize, &MeSetup);
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
Status = AmtGetGbeMac (MacBuffer);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "AMT: Can not read legal value for GBE, use default value.\n"));
|
|
}
|
|
|
|
DataSize = sizeof (MAC_PASS_THRU_CONFIG);
|
|
Status = gRT->GetVariable (MAC_PASS_THRU_VAR, &gAmtMacPassThruConfigGuid, &Attributes, &DataSize, &MacConfig);
|
|
if (EFI_ERROR (Status)) {
|
|
ZeroMem (&MacConfig, sizeof (MAC_PASS_THRU_CONFIG));
|
|
Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS;
|
|
}
|
|
|
|
if ((MacConfig.MacPassThrough != MeSetup.MacPassThrough) ||
|
|
(CompareMem (MacConfig.MacBuffer, MacBuffer, sizeof (MacBuffer)) != 0)) {
|
|
//
|
|
// Send command only if the required change is different from the stored values.
|
|
//
|
|
Status = AmtSetMacPassthrough (MeSetup.MacPassThrough, MacBuffer);
|
|
if (!EFI_ERROR (Status)) {
|
|
MacConfig.MacPassThrough = MeSetup.MacPassThrough;
|
|
CopyMem (MacConfig.MacBuffer, MacBuffer, sizeof (MacBuffer));
|
|
DataSize = sizeof (MAC_PASS_THRU_CONFIG);
|
|
Status = gRT->SetVariable (
|
|
MAC_PASS_THRU_VAR,
|
|
&gAmtMacPassThruConfigGuid,
|
|
Attributes,
|
|
DataSize,
|
|
(VOID *) &MacConfig
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Checks if AMT MAC PassThrough features is supported.
|
|
|
|
@retval TRUE Feature is supported
|
|
@retval FALSE Feature is not supported
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
IsAmtMacPassThroughSupported (
|
|
VOID
|
|
)
|
|
{
|
|
ME_BIOS_PAYLOAD_HOB *MbpHob;
|
|
|
|
MbpHob = GetFirstGuidHob (&gMeBiosPayloadHobGuid);
|
|
if (MbpHob == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (MbpHob->MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType != IntelMeCorporateFw ||
|
|
MbpHob->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.Amt != 1 ||
|
|
MbpHob->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.Amt != 1 ) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
Entry point for the AMT MAC Pass Through Driver.
|
|
Sends AMT Set MAC PassThrough command when Ready To Boot event is signaled.
|
|
|
|
@param[in] ImageHandle - Pointer to the loaded image protocol for this driver
|
|
@param[in] SystemTable - Pointer to the EFI System Table
|
|
|
|
@retval EFI_SUCCESS - Event was created.
|
|
@retval Others - Event was not created.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AmtMacPassThroughEntryPoint (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_EVENT Event;
|
|
EFI_STATUS Status;
|
|
|
|
if (!IsAmtMacPassThroughSupported ()) {
|
|
DEBUG ((DEBUG_WARN, "AmtMacPassThrough not supported on this configuration\n"));
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = gBS->CreateEventEx (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_NOTIFY,
|
|
AmtSendMacAddress,
|
|
NULL,
|
|
&gMePlatformReadyToBootGuid,
|
|
&Event
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
return Status;
|
|
}
|
|
|