mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-22 21:24:35 +02:00
OvmfPkg/CpuHotplugSmm: introduce First SMI Handler for hot-added CPUs
Implement the First SMI Handler for hot-added CPUs, in NASM. Add the interfacing C-language function that the SMM Monarch calls. This function launches and coordinates SMBASE relocation for a hot-added CPU. 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-13-lersek@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
This commit is contained in:
parent
63c89da242
commit
51a6fb4118
@ -24,6 +24,8 @@
|
|||||||
[Sources]
|
[Sources]
|
||||||
ApicId.h
|
ApicId.h
|
||||||
CpuHotplug.c
|
CpuHotplug.c
|
||||||
|
FirstSmiHandler.nasm
|
||||||
|
FirstSmiHandlerContext.h
|
||||||
PostSmmPen.nasm
|
PostSmmPen.nasm
|
||||||
QemuCpuhp.c
|
QemuCpuhp.c
|
||||||
QemuCpuhp.h
|
QemuCpuhp.h
|
||||||
@ -39,9 +41,11 @@
|
|||||||
BaseLib
|
BaseLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
DebugLib
|
DebugLib
|
||||||
|
LocalApicLib
|
||||||
MmServicesTableLib
|
MmServicesTableLib
|
||||||
PcdLib
|
PcdLib
|
||||||
SafeIntLib
|
SafeIntLib
|
||||||
|
SynchronizationLib
|
||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
|
154
OvmfPkg/CpuHotplugSmm/FirstSmiHandler.nasm
Normal file
154
OvmfPkg/CpuHotplugSmm/FirstSmiHandler.nasm
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; @file
|
||||||
|
; Relocate the SMBASE on a hot-added CPU when it services its first SMI.
|
||||||
|
;
|
||||||
|
; Copyright (c) 2020, Red Hat, Inc.
|
||||||
|
;
|
||||||
|
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
;
|
||||||
|
; The routine runs on the hot-added CPU in the following "big real mode",
|
||||||
|
; 16-bit environment; per "SMI HANDLER EXECUTION ENVIRONMENT" in the Intel SDM
|
||||||
|
; (table "Processor Register Initialization in SMM"):
|
||||||
|
;
|
||||||
|
; - CS selector: 0x3000 (most significant 16 bits of SMM_DEFAULT_SMBASE).
|
||||||
|
;
|
||||||
|
; - CS limit: 0xFFFF_FFFF.
|
||||||
|
;
|
||||||
|
; - CS base: SMM_DEFAULT_SMBASE (0x3_0000).
|
||||||
|
;
|
||||||
|
; - IP: SMM_HANDLER_OFFSET (0x8000).
|
||||||
|
;
|
||||||
|
; - ES, SS, DS, FS, GS selectors: 0.
|
||||||
|
;
|
||||||
|
; - ES, SS, DS, FS, GS limits: 0xFFFF_FFFF.
|
||||||
|
;
|
||||||
|
; - ES, SS, DS, FS, GS bases: 0.
|
||||||
|
;
|
||||||
|
; - Operand-size and address-size override prefixes can be used to access the
|
||||||
|
; address space beyond 1MB.
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SECTION .data
|
||||||
|
BITS 16
|
||||||
|
|
||||||
|
;
|
||||||
|
; Bring in SMM_DEFAULT_SMBASE from
|
||||||
|
; "MdePkg/Include/Register/Intel/SmramSaveStateMap.h".
|
||||||
|
;
|
||||||
|
SMM_DEFAULT_SMBASE: equ 0x3_0000
|
||||||
|
|
||||||
|
;
|
||||||
|
; Field offsets in FIRST_SMI_HANDLER_CONTEXT, which resides at
|
||||||
|
; SMM_DEFAULT_SMBASE.
|
||||||
|
;
|
||||||
|
ApicIdGate: equ 0 ; UINT64
|
||||||
|
NewSmbase: equ 8 ; UINT32
|
||||||
|
AboutToLeaveSmm: equ 12 ; UINT8
|
||||||
|
|
||||||
|
;
|
||||||
|
; SMRAM Save State Map field offsets, per the AMD (not Intel) layout that QEMU
|
||||||
|
; implements. Relative to SMM_DEFAULT_SMBASE.
|
||||||
|
;
|
||||||
|
SaveStateRevId: equ 0xFEFC ; UINT32
|
||||||
|
SaveStateSmbase: equ 0xFEF8 ; UINT32
|
||||||
|
SaveStateSmbase64: equ 0xFF00 ; UINT32
|
||||||
|
|
||||||
|
;
|
||||||
|
; CPUID constants, from "MdePkg/Include/Register/Intel/Cpuid.h".
|
||||||
|
;
|
||||||
|
CPUID_SIGNATURE: equ 0x00
|
||||||
|
CPUID_EXTENDED_TOPOLOGY: equ 0x0B
|
||||||
|
CPUID_VERSION_INFO: equ 0x01
|
||||||
|
|
||||||
|
GLOBAL ASM_PFX (mFirstSmiHandler) ; UINT8[]
|
||||||
|
GLOBAL ASM_PFX (mFirstSmiHandlerSize) ; UINT16
|
||||||
|
|
||||||
|
ASM_PFX (mFirstSmiHandler):
|
||||||
|
;
|
||||||
|
; Get our own APIC ID first, so we can contend for ApicIdGate.
|
||||||
|
;
|
||||||
|
; This basically reimplements GetInitialApicId() from
|
||||||
|
; "UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c".
|
||||||
|
;
|
||||||
|
mov eax, CPUID_SIGNATURE
|
||||||
|
cpuid
|
||||||
|
cmp eax, CPUID_EXTENDED_TOPOLOGY
|
||||||
|
jb GetApicIdFromVersionInfo
|
||||||
|
|
||||||
|
mov eax, CPUID_EXTENDED_TOPOLOGY
|
||||||
|
mov ecx, 0
|
||||||
|
cpuid
|
||||||
|
test ebx, 0xFFFF
|
||||||
|
jz GetApicIdFromVersionInfo
|
||||||
|
|
||||||
|
;
|
||||||
|
; EDX has the APIC ID, save it to ESI.
|
||||||
|
;
|
||||||
|
mov esi, edx
|
||||||
|
jmp KnockOnGate
|
||||||
|
|
||||||
|
GetApicIdFromVersionInfo:
|
||||||
|
mov eax, CPUID_VERSION_INFO
|
||||||
|
cpuid
|
||||||
|
shr ebx, 24
|
||||||
|
;
|
||||||
|
; EBX has the APIC ID, save it to ESI.
|
||||||
|
;
|
||||||
|
mov esi, ebx
|
||||||
|
|
||||||
|
KnockOnGate:
|
||||||
|
;
|
||||||
|
; See if ApicIdGate shows our own APIC ID. If so, swap it to MAX_UINT64
|
||||||
|
; (close the gate), and advance. Otherwise, keep knocking.
|
||||||
|
;
|
||||||
|
; InterlockedCompareExchange64():
|
||||||
|
; - Value := &FIRST_SMI_HANDLER_CONTEXT.ApicIdGate
|
||||||
|
; - CompareValue (EDX:EAX) := APIC ID (from ESI)
|
||||||
|
; - ExchangeValue (ECX:EBX) := MAX_UINT64
|
||||||
|
;
|
||||||
|
mov edx, 0
|
||||||
|
mov eax, esi
|
||||||
|
mov ecx, 0xFFFF_FFFF
|
||||||
|
mov ebx, 0xFFFF_FFFF
|
||||||
|
lock cmpxchg8b [ds : dword (SMM_DEFAULT_SMBASE + ApicIdGate)]
|
||||||
|
jz ApicIdMatch
|
||||||
|
pause
|
||||||
|
jmp KnockOnGate
|
||||||
|
|
||||||
|
ApicIdMatch:
|
||||||
|
;
|
||||||
|
; Update the SMBASE field in the SMRAM Save State Map.
|
||||||
|
;
|
||||||
|
; First, calculate the address of the SMBASE field, based on the SMM Revision
|
||||||
|
; ID; store the result in EBX.
|
||||||
|
;
|
||||||
|
mov eax, dword [ds : dword (SMM_DEFAULT_SMBASE + SaveStateRevId)]
|
||||||
|
test eax, 0xFFFF
|
||||||
|
jz LegacySaveStateMap
|
||||||
|
|
||||||
|
mov ebx, SMM_DEFAULT_SMBASE + SaveStateSmbase64
|
||||||
|
jmp UpdateSmbase
|
||||||
|
|
||||||
|
LegacySaveStateMap:
|
||||||
|
mov ebx, SMM_DEFAULT_SMBASE + SaveStateSmbase
|
||||||
|
|
||||||
|
UpdateSmbase:
|
||||||
|
;
|
||||||
|
; Load the new SMBASE value into EAX.
|
||||||
|
;
|
||||||
|
mov eax, dword [ds : dword (SMM_DEFAULT_SMBASE + NewSmbase)]
|
||||||
|
;
|
||||||
|
; Save it to the SMBASE field whose address we calculated in EBX.
|
||||||
|
;
|
||||||
|
mov dword [ds : dword ebx], eax
|
||||||
|
;
|
||||||
|
; Set AboutToLeaveSmm.
|
||||||
|
;
|
||||||
|
mov byte [ds : dword (SMM_DEFAULT_SMBASE + AboutToLeaveSmm)], 1
|
||||||
|
;
|
||||||
|
; We're done; leave SMM and continue to the pen.
|
||||||
|
;
|
||||||
|
rsm
|
||||||
|
|
||||||
|
ASM_PFX (mFirstSmiHandlerSize):
|
||||||
|
dw $ - ASM_PFX (mFirstSmiHandler)
|
47
OvmfPkg/CpuHotplugSmm/FirstSmiHandlerContext.h
Normal file
47
OvmfPkg/CpuHotplugSmm/FirstSmiHandlerContext.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/** @file
|
||||||
|
Define the FIRST_SMI_HANDLER_CONTEXT structure, which is an exchange area
|
||||||
|
between the SMM Monarch and the hot-added CPU, for relocating the SMBASE of
|
||||||
|
the hot-added CPU.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Red Hat, Inc.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef FIRST_SMI_HANDLER_CONTEXT_H_
|
||||||
|
#define FIRST_SMI_HANDLER_CONTEXT_H_
|
||||||
|
|
||||||
|
//
|
||||||
|
// The following structure is used to communicate between the SMM Monarch
|
||||||
|
// (running the root MMI handler) and the hot-added CPU (handling its first
|
||||||
|
// SMI). It is placed at SMM_DEFAULT_SMBASE, which is in SMRAM under QEMU's
|
||||||
|
// "SMRAM at default SMBASE" feature.
|
||||||
|
//
|
||||||
|
#pragma pack (1)
|
||||||
|
typedef struct {
|
||||||
|
//
|
||||||
|
// When ApicIdGate is MAX_UINT64, then no hot-added CPU may proceed with
|
||||||
|
// SMBASE relocation.
|
||||||
|
//
|
||||||
|
// Otherwise, the hot-added CPU whose APIC ID equals ApicIdGate may proceed
|
||||||
|
// with SMBASE relocation.
|
||||||
|
//
|
||||||
|
// This field is intentionally wider than APIC_ID (UINT32) because we need a
|
||||||
|
// "gate locked" value that is different from all possible APIC_IDs.
|
||||||
|
//
|
||||||
|
UINT64 ApicIdGate;
|
||||||
|
//
|
||||||
|
// The new SMBASE value for the hot-added CPU to set in the SMRAM Save State
|
||||||
|
// Map, before leaving SMM with the RSM instruction.
|
||||||
|
//
|
||||||
|
UINT32 NewSmbase;
|
||||||
|
//
|
||||||
|
// The hot-added CPU sets this field to 1 right before executing the RSM
|
||||||
|
// instruction. This tells the SMM Monarch to proceed to polling the last
|
||||||
|
// byte of the normal RAM reserved page (Post-SMM Pen).
|
||||||
|
//
|
||||||
|
UINT8 AboutToLeaveSmm;
|
||||||
|
} FIRST_SMI_HANDLER_CONTEXT;
|
||||||
|
#pragma pack ()
|
||||||
|
|
||||||
|
#endif // FIRST_SMI_HANDLER_CONTEXT_H_
|
@ -7,13 +7,21 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include <Base.h> // BASE_1MB
|
#include <Base.h> // BASE_1MB
|
||||||
|
#include <Library/BaseLib.h> // CpuPause()
|
||||||
#include <Library/BaseMemoryLib.h> // CopyMem()
|
#include <Library/BaseMemoryLib.h> // CopyMem()
|
||||||
#include <Library/DebugLib.h> // DEBUG()
|
#include <Library/DebugLib.h> // DEBUG()
|
||||||
|
#include <Library/LocalApicLib.h> // SendInitSipiSipi()
|
||||||
|
#include <Library/SynchronizationLib.h> // InterlockedCompareExchange64()
|
||||||
|
#include <Register/Intel/SmramSaveStateMap.h> // SMM_DEFAULT_SMBASE
|
||||||
|
|
||||||
|
#include "FirstSmiHandlerContext.h" // FIRST_SMI_HANDLER_CONTEXT
|
||||||
|
|
||||||
#include "Smbase.h"
|
#include "Smbase.h"
|
||||||
|
|
||||||
extern CONST UINT8 mPostSmmPen[];
|
extern CONST UINT8 mPostSmmPen[];
|
||||||
extern CONST UINT16 mPostSmmPenSize;
|
extern CONST UINT16 mPostSmmPenSize;
|
||||||
|
extern CONST UINT8 mFirstSmiHandler[];
|
||||||
|
extern CONST UINT16 mFirstSmiHandlerSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Allocate a non-SMRAM reserved memory page for the Post-SMM Pen for hot-added
|
Allocate a non-SMRAM reserved memory page for the Post-SMM Pen for hot-added
|
||||||
@ -108,3 +116,152 @@ SmbaseReleasePostSmmPen (
|
|||||||
{
|
{
|
||||||
BootServices->FreePages (PenAddress, 1);
|
BootServices->FreePages (PenAddress, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Place the handler routine for the first SMIs of hot-added CPUs at
|
||||||
|
(SMM_DEFAULT_SMBASE + SMM_HANDLER_OFFSET).
|
||||||
|
|
||||||
|
Note that this effects an "SMRAM to SMRAM" copy.
|
||||||
|
|
||||||
|
Additionally, shut the APIC ID gate in FIRST_SMI_HANDLER_CONTEXT.
|
||||||
|
|
||||||
|
This function may only be called from the entry point function of the driver,
|
||||||
|
and only after PcdQ35SmramAtDefaultSmbase has been determined to be TRUE.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SmbaseInstallFirstSmiHandler (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FIRST_SMI_HANDLER_CONTEXT *Context;
|
||||||
|
|
||||||
|
CopyMem ((VOID *)(UINTN)(SMM_DEFAULT_SMBASE + SMM_HANDLER_OFFSET),
|
||||||
|
mFirstSmiHandler, mFirstSmiHandlerSize);
|
||||||
|
|
||||||
|
Context = (VOID *)(UINTN)SMM_DEFAULT_SMBASE;
|
||||||
|
Context->ApicIdGate = MAX_UINT64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Relocate the SMBASE on a hot-added CPU. Then pen the hot-added CPU in the
|
||||||
|
normal RAM reserved memory page, set up earlier with
|
||||||
|
SmbaseAllocatePostSmmPen() and SmbaseReinstallPostSmmPen().
|
||||||
|
|
||||||
|
The SMM Monarch is supposed to call this function from the root MMI handler.
|
||||||
|
|
||||||
|
The SMM Monarch is responsible for calling SmbaseInstallFirstSmiHandler(),
|
||||||
|
SmbaseAllocatePostSmmPen(), and SmbaseReinstallPostSmmPen() before calling
|
||||||
|
this function.
|
||||||
|
|
||||||
|
If the OS maliciously boots the hot-added CPU ahead of letting the ACPI CPU
|
||||||
|
hotplug event handler broadcast the CPU hotplug MMI, then the hot-added CPU
|
||||||
|
returns to the OS rather than to the pen, upon RSM. In that case, this
|
||||||
|
function will hang forever (unless the OS happens to signal back through the
|
||||||
|
last byte of the pen page).
|
||||||
|
|
||||||
|
@param[in] ApicId The APIC ID of the hot-added CPU whose SMBASE should
|
||||||
|
be relocated.
|
||||||
|
|
||||||
|
@param[in] Smbase The new SMBASE address. The root MMI handler is
|
||||||
|
responsible for passing in a free ("unoccupied")
|
||||||
|
SMBASE address that was pre-configured by
|
||||||
|
PiSmmCpuDxeSmm in CPU_HOT_PLUG_DATA.
|
||||||
|
|
||||||
|
@param[in] PenAddress The address of the Post-SMM Pen for hot-added CPUs, as
|
||||||
|
returned by SmbaseAllocatePostSmmPen(), and installed
|
||||||
|
by SmbaseReinstallPostSmmPen().
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The SMBASE of the hot-added CPU with APIC ID
|
||||||
|
ApicId has been relocated to Smbase. The
|
||||||
|
hot-added CPU has reported back about leaving
|
||||||
|
SMM.
|
||||||
|
|
||||||
|
@retval EFI_PROTOCOL_ERROR Synchronization bug encountered around
|
||||||
|
FIRST_SMI_HANDLER_CONTEXT.ApicIdGate.
|
||||||
|
|
||||||
|
@retval EFI_INVALID_PARAMETER Smbase does not fit in 32 bits. No relocation
|
||||||
|
has been attempted.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
SmbaseRelocate (
|
||||||
|
IN APIC_ID ApicId,
|
||||||
|
IN UINTN Smbase,
|
||||||
|
IN UINT32 PenAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
volatile UINT8 *SmmVacated;
|
||||||
|
volatile FIRST_SMI_HANDLER_CONTEXT *Context;
|
||||||
|
UINT64 ExchangeResult;
|
||||||
|
|
||||||
|
if (Smbase > MAX_UINT32) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
DEBUG ((DEBUG_ERROR, "%a: ApicId=" FMT_APIC_ID " Smbase=0x%Lx: %r\n",
|
||||||
|
__FUNCTION__, ApicId, (UINT64)Smbase, Status));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmmVacated = (UINT8 *)(UINTN)PenAddress + (EFI_PAGE_SIZE - 1);
|
||||||
|
Context = (VOID *)(UINTN)SMM_DEFAULT_SMBASE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear AboutToLeaveSmm, so we notice when the hot-added CPU is just about
|
||||||
|
// to reach RSM, and we can proceed to polling the last byte of the reserved
|
||||||
|
// page (which could be attacked by the OS).
|
||||||
|
//
|
||||||
|
Context->AboutToLeaveSmm = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear the last byte of the reserved page, so we notice when the hot-added
|
||||||
|
// CPU checks back in from the pen.
|
||||||
|
//
|
||||||
|
*SmmVacated = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Boot the hot-added CPU.
|
||||||
|
//
|
||||||
|
// If the OS is benign, and so the hot-added CPU is still in RESET state,
|
||||||
|
// then the broadcast SMI is still pending for it; it will now launch
|
||||||
|
// directly into SMM.
|
||||||
|
//
|
||||||
|
// If the OS is malicious, the hot-added CPU has been booted already, and so
|
||||||
|
// it is already spinning on the APIC ID gate. In that case, the
|
||||||
|
// INIT-SIPI-SIPI below will be ignored.
|
||||||
|
//
|
||||||
|
SendInitSipiSipi (ApicId, PenAddress);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Expose the desired new SMBASE value to the hot-added CPU.
|
||||||
|
//
|
||||||
|
Context->NewSmbase = (UINT32)Smbase;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Un-gate SMBASE relocation for the hot-added CPU whose APIC ID is ApicId.
|
||||||
|
//
|
||||||
|
ExchangeResult = InterlockedCompareExchange64 (&Context->ApicIdGate,
|
||||||
|
MAX_UINT64, ApicId);
|
||||||
|
if (ExchangeResult != MAX_UINT64) {
|
||||||
|
Status = EFI_PROTOCOL_ERROR;
|
||||||
|
DEBUG ((DEBUG_ERROR, "%a: ApicId=" FMT_APIC_ID " ApicIdGate=0x%Lx: %r\n",
|
||||||
|
__FUNCTION__, ApicId, ExchangeResult, Status));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wait until the hot-added CPU is just about to execute RSM.
|
||||||
|
//
|
||||||
|
while (Context->AboutToLeaveSmm == 0) {
|
||||||
|
CpuPause ();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now wait until the hot-added CPU reports back from the pen (or the OS
|
||||||
|
// attacks the last byte of the reserved page).
|
||||||
|
//
|
||||||
|
while (*SmmVacated == 0) {
|
||||||
|
CpuPause ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include <Uefi/UefiBaseType.h> // EFI_STATUS
|
#include <Uefi/UefiBaseType.h> // EFI_STATUS
|
||||||
#include <Uefi/UefiSpec.h> // EFI_BOOT_SERVICES
|
#include <Uefi/UefiSpec.h> // EFI_BOOT_SERVICES
|
||||||
|
|
||||||
|
#include "ApicId.h" // APIC_ID
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
SmbaseAllocatePostSmmPen (
|
SmbaseAllocatePostSmmPen (
|
||||||
OUT UINT32 *PenAddress,
|
OUT UINT32 *PenAddress,
|
||||||
@ -29,4 +31,16 @@ SmbaseReleasePostSmmPen (
|
|||||||
IN CONST EFI_BOOT_SERVICES *BootServices
|
IN CONST EFI_BOOT_SERVICES *BootServices
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SmbaseInstallFirstSmiHandler (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
SmbaseRelocate (
|
||||||
|
IN APIC_ID ApicId,
|
||||||
|
IN UINTN Smbase,
|
||||||
|
IN UINT32 PenAddress
|
||||||
|
);
|
||||||
|
|
||||||
#endif // SMBASE_H_
|
#endif // SMBASE_H_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user