mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
OvmfPkg/CpuHotplugSmm: introduce skeleton for CPU Hotplug SMM driver
Add a new SMM driver skeleton that registers a root SMI handler, and checks if the SMI control value (written to 0xB2) indicates a CPU hotplug SMI. QEMU's ACPI payload will cause the OS to raise a broadcast SMI when a CPU hotplug event occurs, namely by writing value 4 to IO Port 0xB2. In other words, control value 4 is now allocated for this purpose; introduce the ICH9_APM_CNT_CPU_HOTPLUG macro for it. The standard identifiers in this driver use the new MM (Management Mode) terminology from the PI spec, not the earlier SMM (System Management Mode) terms. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1512 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20200226221156.29589-7-lersek@redhat.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
This commit is contained in:
parent
49df3fcee1
commit
17efae27ac
OvmfPkg
CpuHotplugSmm
Include/IndustryStandard
OvmfPkgIa32.dscOvmfPkgIa32.fdfOvmfPkgIa32X64.dscOvmfPkgIa32X64.fdfOvmfPkgX64.dscOvmfPkgX64.fdf
191
OvmfPkg/CpuHotplugSmm/CpuHotplug.c
Normal file
191
OvmfPkg/CpuHotplugSmm/CpuHotplug.c
Normal file
@ -0,0 +1,191 @@
|
||||
/** @file
|
||||
Root SMI handler for VCPU hotplug SMIs.
|
||||
|
||||
Copyright (c) 2020, Red Hat, Inc.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/Q35MchIch9.h> // ICH9_APM_CNT
|
||||
#include <Library/BaseLib.h> // CpuDeadLoop()
|
||||
#include <Library/DebugLib.h> // ASSERT()
|
||||
#include <Library/MmServicesTableLib.h> // gMmst
|
||||
#include <Library/PcdLib.h> // PcdGetBool()
|
||||
#include <Protocol/MmCpuIo.h> // EFI_MM_CPU_IO_PROTOCOL
|
||||
#include <Uefi/UefiBaseType.h> // EFI_STATUS
|
||||
|
||||
//
|
||||
// We use this protocol for accessing IO Ports.
|
||||
//
|
||||
STATIC EFI_MM_CPU_IO_PROTOCOL *mMmCpuIo;
|
||||
//
|
||||
// Represents the registration of the CPU Hotplug MMI handler.
|
||||
//
|
||||
STATIC EFI_HANDLE mDispatchHandle;
|
||||
|
||||
|
||||
/**
|
||||
CPU Hotplug MMI handler function.
|
||||
|
||||
This is a root MMI handler.
|
||||
|
||||
@param[in] DispatchHandle The unique handle assigned to this handler by
|
||||
EFI_MM_SYSTEM_TABLE.MmiHandlerRegister().
|
||||
|
||||
@param[in] Context Context passed in by
|
||||
EFI_MM_SYSTEM_TABLE.MmiManage(). Due to
|
||||
CpuHotplugMmi() being a root MMI handler,
|
||||
Context is ASSERT()ed to be NULL.
|
||||
|
||||
@param[in,out] CommBuffer Ignored, due to CpuHotplugMmi() being a root
|
||||
MMI handler.
|
||||
|
||||
@param[in,out] CommBufferSize Ignored, due to CpuHotplugMmi() being a root
|
||||
MMI handler.
|
||||
|
||||
@retval EFI_SUCCESS The MMI was handled and the MMI
|
||||
source was quiesced. When returned
|
||||
by a non-root MMI handler,
|
||||
EFI_SUCCESS terminates the
|
||||
processing of MMI handlers in
|
||||
EFI_MM_SYSTEM_TABLE.MmiManage().
|
||||
For a root MMI handler (i.e., for
|
||||
the present function too),
|
||||
EFI_SUCCESS behaves identically to
|
||||
EFI_WARN_INTERRUPT_SOURCE_QUIESCED,
|
||||
as further root MMI handlers are
|
||||
going to be called by
|
||||
EFI_MM_SYSTEM_TABLE.MmiManage()
|
||||
anyway.
|
||||
|
||||
@retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The MMI source has been quiesced,
|
||||
but other handlers should still
|
||||
be called.
|
||||
|
||||
@retval EFI_WARN_INTERRUPT_SOURCE_PENDING The MMI source is still pending,
|
||||
and other handlers should still
|
||||
be called.
|
||||
|
||||
@retval EFI_INTERRUPT_PENDING The MMI source could not be
|
||||
quiesced.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuHotplugMmi (
|
||||
IN EFI_HANDLE DispatchHandle,
|
||||
IN CONST VOID *Context OPTIONAL,
|
||||
IN OUT VOID *CommBuffer OPTIONAL,
|
||||
IN OUT UINTN *CommBufferSize OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 ApmControl;
|
||||
|
||||
//
|
||||
// Assert that we are entering this function due to our root MMI handler
|
||||
// registration.
|
||||
//
|
||||
ASSERT (DispatchHandle == mDispatchHandle);
|
||||
//
|
||||
// When MmiManage() is invoked to process root MMI handlers, the caller (the
|
||||
// MM Core) is expected to pass in a NULL Context. MmiManage() then passes
|
||||
// the same NULL Context to individual handlers.
|
||||
//
|
||||
ASSERT (Context == NULL);
|
||||
//
|
||||
// Read the MMI command value from the APM Control Port, to see if this is an
|
||||
// MMI we should care about.
|
||||
//
|
||||
Status = mMmCpuIo->Io.Read (mMmCpuIo, MM_IO_UINT8, ICH9_APM_CNT, 1,
|
||||
&ApmControl);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: failed to read ICH9_APM_CNT: %r\n", __FUNCTION__,
|
||||
Status));
|
||||
//
|
||||
// We couldn't even determine if the MMI was for us or not.
|
||||
//
|
||||
goto Fatal;
|
||||
}
|
||||
|
||||
if (ApmControl != ICH9_APM_CNT_CPU_HOTPLUG) {
|
||||
//
|
||||
// The MMI is not for us.
|
||||
//
|
||||
return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
|
||||
}
|
||||
|
||||
//
|
||||
// We've handled this MMI.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
|
||||
Fatal:
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
//
|
||||
// We couldn't handle this MMI.
|
||||
//
|
||||
return EFI_INTERRUPT_PENDING;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Entry point function of this driver.
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuHotplugEntry (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// This module should only be included when SMM support is required.
|
||||
//
|
||||
ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
|
||||
//
|
||||
// This driver depends on the dynamically detected "SMRAM at default SMBASE"
|
||||
// feature.
|
||||
//
|
||||
if (!PcdGetBool (PcdQ35SmramAtDefaultSmbase)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Errors from here on are fatal; we cannot allow the boot to proceed if we
|
||||
// can't set up this driver to handle CPU hotplug.
|
||||
//
|
||||
// First, collect the protocols needed later. All of these protocols are
|
||||
// listed in our module DEPEX.
|
||||
//
|
||||
Status = gMmst->MmLocateProtocol (&gEfiMmCpuIoProtocolGuid,
|
||||
NULL /* Registration */, (VOID **)&mMmCpuIo);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: locate MmCpuIo: %r\n", __FUNCTION__, Status));
|
||||
goto Fatal;
|
||||
}
|
||||
|
||||
//
|
||||
// Register the handler for the CPU Hotplug MMI.
|
||||
//
|
||||
Status = gMmst->MmiHandlerRegister (
|
||||
CpuHotplugMmi,
|
||||
NULL, // HandlerType: root MMI handler
|
||||
&mDispatchHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: MmiHandlerRegister(): %r\n", __FUNCTION__,
|
||||
Status));
|
||||
goto Fatal;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
Fatal:
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
return Status;
|
||||
}
|
48
OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
Normal file
48
OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
Normal file
@ -0,0 +1,48 @@
|
||||
## @file
|
||||
# Root SMI handler for VCPU hotplug SMIs.
|
||||
#
|
||||
# Copyright (c) 2020, Red Hat, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 1.29
|
||||
PI_SPECIFICATION_VERSION = 0x00010046 # PI-1.7.0
|
||||
BASE_NAME = CpuHotplugSmm
|
||||
FILE_GUID = 84EEA114-C6BE-4445-8F90-51D97863E363
|
||||
MODULE_TYPE = DXE_SMM_DRIVER
|
||||
ENTRY_POINT = CpuHotplugEntry
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build
|
||||
# tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
CpuHotplug.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
OvmfPkg/OvmfPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
DebugLib
|
||||
MmServicesTableLib
|
||||
PcdLib
|
||||
UefiDriverEntryPoint
|
||||
|
||||
[Protocols]
|
||||
gEfiMmCpuIoProtocolGuid ## CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase ## CONSUMES
|
||||
|
||||
[FeaturePcd]
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiMmCpuIoProtocolGuid
|
@ -109,8 +109,9 @@
|
||||
//
|
||||
// IO ports
|
||||
//
|
||||
#define ICH9_APM_CNT 0xB2
|
||||
#define ICH9_APM_STS 0xB3
|
||||
#define ICH9_APM_CNT 0xB2
|
||||
#define ICH9_APM_CNT_CPU_HOTPLUG 0x04
|
||||
#define ICH9_APM_STS 0xB3
|
||||
|
||||
#define ICH9_CPU_HOTPLUG_BASE 0x0CD8
|
||||
|
||||
|
@ -880,6 +880,7 @@
|
||||
#
|
||||
# Privileged drivers (DXE_SMM_DRIVER modules)
|
||||
#
|
||||
OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
|
||||
UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
|
||||
MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf {
|
||||
<LibraryClasses>
|
||||
|
@ -322,6 +322,7 @@ INF OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
|
||||
INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
|
||||
INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
|
||||
INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
|
||||
INF OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
|
||||
INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
|
||||
INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
|
||||
INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
|
||||
|
@ -893,6 +893,7 @@
|
||||
#
|
||||
# Privileged drivers (DXE_SMM_DRIVER modules)
|
||||
#
|
||||
OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
|
||||
UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
|
||||
MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf {
|
||||
<LibraryClasses>
|
||||
|
@ -329,6 +329,7 @@ INF OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
|
||||
INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
|
||||
INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
|
||||
INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
|
||||
INF OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
|
||||
INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
|
||||
INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
|
||||
INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
|
||||
|
@ -891,6 +891,7 @@
|
||||
#
|
||||
# Privileged drivers (DXE_SMM_DRIVER modules)
|
||||
#
|
||||
OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
|
||||
UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
|
||||
MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf {
|
||||
<LibraryClasses>
|
||||
|
@ -329,6 +329,7 @@ INF OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
|
||||
INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
|
||||
INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
|
||||
INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
|
||||
INF OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
|
||||
INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
|
||||
INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
|
||||
INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
|
||||
|
Loading…
x
Reference in New Issue
Block a user