audk/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c

76 lines
2.3 KiB
C
Raw Normal View History

/** @file
Semaphore mechanism to indicate to the BSP that an AP has exited SMM
after SMBASE relocation.
Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "PiSmmCpuDxeSmm.h"
UefiCpuPkg/PiSmmCpuDxeSmm: remove DBs from SmmRelocationSemaphoreComplete32() (1) SmmRelocationSemaphoreComplete32() runs in 32-bit mode, so wrap it in a (BITS 32 ... BITS 64) bracket. (2) SmmRelocationSemaphoreComplete32() currently compiles to: > 000002AE C6050000000001 mov byte [dword 0x0],0x1 > 000002B5 FF2500000000 jmp dword [dword 0x0] where the first instruction is patched with the contents of "mRebasedFlag" (so that (*mRebasedFlag) is set to 1), and the second instruction is patched with the address of "mSmmRelocationOriginalAddress" (so that we jump to "mSmmRelocationOriginalAddress"). In its current form the first instruction could not be patched with PatchInstructionX86(), given that the operand to patch is not encoded in the trailing bytes of the instruction. Therefore, adopt an EAX-based version, inspired by both the IA32 and X64 variants of SmmRelocationSemaphoreComplete(): > 000002AE 50 push eax > 000002AF B800000000 mov eax,0x0 > 000002B4 C60001 mov byte [eax],0x1 > 000002B7 58 pop eax > 000002B8 FF2500000000 jmp dword [dword 0x0] Here both instructions can be patched with PatchInstructionX86(), and the DBs can be replaced with native NASM syntax. (3) Turn the "mRebasedFlagAddr32" and "mSmmRelocationOriginalAddressPtr32" variables into markers that suit PatchInstructionX86(). Cc: Eric Dong <eric.dong@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=866 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
2018-02-02 05:36:22 +01:00
X86_ASSEMBLY_PATCH_LABEL gPatchSmmRelocationOriginalAddressPtr32;
X86_ASSEMBLY_PATCH_LABEL gPatchRebasedFlagAddr32;
UINTN mSmmRelocationOriginalAddress;
volatile BOOLEAN *mRebasedFlag;
/**
AP Semaphore operation in 32-bit mode while BSP runs in 64-bit mode.
**/
VOID
SmmRelocationSemaphoreComplete32 (
VOID
);
/**
Hook return address of SMM Save State so that semaphore code
can be executed immediately after AP exits SMM to indicate to
the BSP that an AP has exited SMM after SMBASE relocation.
@param[in] CpuIndex The processor index.
@param[in] RebasedFlag A pointer to a flag that is set to TRUE
immediately after AP exits SMM.
**/
VOID
SemaphoreHook (
IN UINTN CpuIndex,
IN volatile BOOLEAN *RebasedFlag
)
{
SMRAM_SAVE_STATE_MAP *CpuState;
UINTN TempValue;
mRebasedFlag = RebasedFlag;
UefiCpuPkg/PiSmmCpuDxeSmm: remove DBs from SmmRelocationSemaphoreComplete32() (1) SmmRelocationSemaphoreComplete32() runs in 32-bit mode, so wrap it in a (BITS 32 ... BITS 64) bracket. (2) SmmRelocationSemaphoreComplete32() currently compiles to: > 000002AE C6050000000001 mov byte [dword 0x0],0x1 > 000002B5 FF2500000000 jmp dword [dword 0x0] where the first instruction is patched with the contents of "mRebasedFlag" (so that (*mRebasedFlag) is set to 1), and the second instruction is patched with the address of "mSmmRelocationOriginalAddress" (so that we jump to "mSmmRelocationOriginalAddress"). In its current form the first instruction could not be patched with PatchInstructionX86(), given that the operand to patch is not encoded in the trailing bytes of the instruction. Therefore, adopt an EAX-based version, inspired by both the IA32 and X64 variants of SmmRelocationSemaphoreComplete(): > 000002AE 50 push eax > 000002AF B800000000 mov eax,0x0 > 000002B4 C60001 mov byte [eax],0x1 > 000002B7 58 pop eax > 000002B8 FF2500000000 jmp dword [dword 0x0] Here both instructions can be patched with PatchInstructionX86(), and the DBs can be replaced with native NASM syntax. (3) Turn the "mRebasedFlagAddr32" and "mSmmRelocationOriginalAddressPtr32" variables into markers that suit PatchInstructionX86(). Cc: Eric Dong <eric.dong@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=866 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
2018-02-02 05:36:22 +01:00
PatchInstructionX86 (
gPatchRebasedFlagAddr32,
(UINT32)(UINTN)mRebasedFlag,
4
);
CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
mSmmRelocationOriginalAddress = HookReturnFromSmm (
CpuIndex,
CpuState,
(UINT64)(UINTN)&SmmRelocationSemaphoreComplete32,
(UINT64)(UINTN)&SmmRelocationSemaphoreComplete
);
//
// Use temp value to fix ICC complier warning
//
TempValue = (UINTN)&mSmmRelocationOriginalAddress;
UefiCpuPkg/PiSmmCpuDxeSmm: remove DBs from SmmRelocationSemaphoreComplete32() (1) SmmRelocationSemaphoreComplete32() runs in 32-bit mode, so wrap it in a (BITS 32 ... BITS 64) bracket. (2) SmmRelocationSemaphoreComplete32() currently compiles to: > 000002AE C6050000000001 mov byte [dword 0x0],0x1 > 000002B5 FF2500000000 jmp dword [dword 0x0] where the first instruction is patched with the contents of "mRebasedFlag" (so that (*mRebasedFlag) is set to 1), and the second instruction is patched with the address of "mSmmRelocationOriginalAddress" (so that we jump to "mSmmRelocationOriginalAddress"). In its current form the first instruction could not be patched with PatchInstructionX86(), given that the operand to patch is not encoded in the trailing bytes of the instruction. Therefore, adopt an EAX-based version, inspired by both the IA32 and X64 variants of SmmRelocationSemaphoreComplete(): > 000002AE 50 push eax > 000002AF B800000000 mov eax,0x0 > 000002B4 C60001 mov byte [eax],0x1 > 000002B7 58 pop eax > 000002B8 FF2500000000 jmp dword [dword 0x0] Here both instructions can be patched with PatchInstructionX86(), and the DBs can be replaced with native NASM syntax. (3) Turn the "mRebasedFlagAddr32" and "mSmmRelocationOriginalAddressPtr32" variables into markers that suit PatchInstructionX86(). Cc: Eric Dong <eric.dong@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=866 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
2018-02-02 05:36:22 +01:00
PatchInstructionX86 (
gPatchSmmRelocationOriginalAddressPtr32,
(UINT32)TempValue,
4
);
}