2015-10-19 21:12:53 +02:00
|
|
|
/** @file
|
|
|
|
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
|
|
|
|
|
2024-05-10 09:15:27 +02:00
|
|
|
Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
|
2017-02-26 18:43:07 +01:00
|
|
|
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
|
2024-05-07 04:48:03 +02:00
|
|
|
Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
|
2017-02-26 18:43:07 +01:00
|
|
|
|
2019-04-04 01:07:22 +02:00
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
2015-10-19 21:12:53 +02:00
|
|
|
|
|
|
|
**/
|
|
|
|
|
2024-06-24 11:56:00 +02:00
|
|
|
#include "PiSmmCpuCommon.h"
|
2015-10-19 21:12:53 +02:00
|
|
|
|
2024-05-07 04:48:03 +02:00
|
|
|
/**
|
|
|
|
Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from gEfiMpServiceProtocolGuid.
|
|
|
|
|
|
|
|
@param[out] NumberOfCpus Pointer to NumberOfCpus.
|
|
|
|
@param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus.
|
|
|
|
|
|
|
|
@retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer.
|
|
|
|
**/
|
|
|
|
EFI_PROCESSOR_INFORMATION *
|
|
|
|
GetMpInformationFromMpServices (
|
|
|
|
OUT UINTN *NumberOfCpus,
|
|
|
|
OUT UINTN *MaxNumberOfCpus
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINTN Index;
|
|
|
|
UINTN NumberOfEnabledProcessors;
|
|
|
|
UINTN NumberOfProcessors;
|
|
|
|
EFI_MP_SERVICES_PROTOCOL *MpService;
|
|
|
|
EFI_PROCESSOR_INFORMATION *ProcessorInfo;
|
|
|
|
|
|
|
|
if ((NumberOfCpus == NULL) || (MaxNumberOfCpus == NULL)) {
|
|
|
|
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcessorInfo = NULL;
|
|
|
|
*NumberOfCpus = 0;
|
|
|
|
*MaxNumberOfCpus = 0;
|
|
|
|
|
|
|
|
/// Get the MP Services Protocol
|
|
|
|
Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpService);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the number of processors
|
|
|
|
Status = MpService->GetNumberOfProcessors (MpService, &NumberOfProcessors, &NumberOfEnabledProcessors);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT (NumberOfProcessors <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
|
|
|
|
|
|
|
|
/// Allocate buffer for processor information
|
|
|
|
ProcessorInfo = AllocateZeroPool (sizeof (EFI_PROCESSOR_INFORMATION) * NumberOfProcessors);
|
|
|
|
if (ProcessorInfo == NULL) {
|
|
|
|
ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get processor information
|
|
|
|
for (Index = 0; Index < NumberOfProcessors; Index++) {
|
|
|
|
Status = MpService->GetProcessorInfo (MpService, Index | CPU_V2_EXTENDED_TOPOLOGY, &ProcessorInfo[Index]);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
FreePool (ProcessorInfo);
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to get processor information for processor %d\n", __func__, Index));
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*NumberOfCpus = NumberOfEnabledProcessors;
|
|
|
|
|
|
|
|
ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
|
|
|
|
//
|
|
|
|
// If support CPU hot plug, we need to allocate resources for possibly hot-added processors
|
|
|
|
//
|
|
|
|
if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
|
|
|
|
*MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
|
|
|
|
} else {
|
|
|
|
*MaxNumberOfCpus = *NumberOfCpus;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ProcessorInfo;
|
|
|
|
}
|
|
|
|
|
2023-11-24 08:55:34 +01:00
|
|
|
/**
|
2024-06-24 13:26:23 +02:00
|
|
|
The module Entry Point of the CPU SMM driver.
|
2023-11-24 08:55:34 +01:00
|
|
|
|
2024-06-24 13:26:23 +02:00
|
|
|
@param ImageHandle The firmware allocated handle for the EFI image.
|
|
|
|
@param SystemTable A pointer to the EFI System Table.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS The entry point is executed successfully.
|
|
|
|
@retval Other Some error occurs when executing this entry point.
|
2023-11-24 08:55:34 +01:00
|
|
|
|
|
|
|
**/
|
2024-06-24 13:26:23 +02:00
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
PiCpuSmmEntry (
|
|
|
|
IN EFI_HANDLE ImageHandle,
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
2023-11-24 08:55:34 +01:00
|
|
|
)
|
|
|
|
{
|
2024-06-24 13:26:23 +02:00
|
|
|
EFI_STATUS Status;
|
2024-05-07 04:48:03 +02:00
|
|
|
|
2024-06-24 13:26:23 +02:00
|
|
|
//
|
|
|
|
// Save the PcdPteMemoryEncryptionAddressOrMask value into a global variable.
|
|
|
|
// Make sure AddressEncMask is contained to smallest supported address field.
|
|
|
|
//
|
|
|
|
mAddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
|
|
|
|
DEBUG ((DEBUG_INFO, "mAddressEncMask = 0x%lx\n", mAddressEncMask));
|
2023-11-24 08:55:34 +01:00
|
|
|
|
2024-06-24 13:26:23 +02:00
|
|
|
Status = PiSmmCpuEntryCommon ();
|
2023-11-24 08:55:34 +01:00
|
|
|
|
2024-06-24 13:26:23 +02:00
|
|
|
ASSERT_EFI_ERROR (Status);
|
2015-10-19 21:12:53 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// Install the SMM Configuration Protocol onto a new handle on the handle database.
|
|
|
|
// The entire SMM Configuration Protocol is allocated from SMRAM, so only a pointer
|
|
|
|
// to an SMRAM address will be present in the handle database
|
|
|
|
//
|
|
|
|
Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces (
|
|
|
|
&gSmmCpuPrivate->SmmCpuHandle,
|
|
|
|
&gEfiSmmConfigurationProtocolGuid,
|
|
|
|
&gSmmCpuPrivate->SmmConfiguration,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Expose address of CPU Hot Plug Data structure if CPU hot plug is supported.
|
|
|
|
//
|
|
|
|
if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
|
2015-10-27 17:15:03 +01:00
|
|
|
Status = PcdSet64S (PcdCpuHotPlugDataAddress, (UINT64)(UINTN)&mCpuHotPlugData);
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
2015-10-19 21:12:53 +02:00
|
|
|
}
|
|
|
|
|
2024-06-24 13:26:23 +02:00
|
|
|
return Status;
|
2015-11-25 05:28:46 +01:00
|
|
|
}
|