Files
system76-edk2/UefiCpuPkg/Library/SmmRelocationLib/Ia32/SmmInit.nasm
Jiaxin Wu 51fcd2023b UefiCpuPkg/SmmRelocationLib: Add SmmRelocationLib library instance
This patch just separates the smbase relocation logic from
PiSmmCpuDxeSmm driver, and moves to the SmmRelocationInit
interface. It maintains the original implementation of most
functions and leaves the definitions of global variables
intact. Further refinements to the code are planned for
subsequent patches.

Platform shall consume the interface for the smbase
relocation if need SMM support.

Note:
Before using SmmRelocationLib, the PiSmmCpuDxeSmm driver
allocates the SMRAM to be used for SMI handler and Save
state area of each processor from Smst->AllocatePages().
With SmmRelocationLib, the SMRAM allocation for SMI
handlers and Save state areas is moved to early PEI
phase (Smst->AllocatePages() service is not available).
So, the allocation is done by splitting the SMRAM out of
the SMRAM regions reported from gEfiSmmSMramMemoryGuid.

So, Platform must produce the gEfiSmmSMramMemoryGuid HOB
for SmmRelocationLib usage.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Zeng Star <star.zeng@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2024-05-08 01:53:58 +00:00

152 lines
4.6 KiB
NASM

;------------------------------------------------------------------------------ ;
; Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; SmmInit.nasm
;
; Abstract:
;
; Functions for relocating SMBASE's for all processors
;
;-------------------------------------------------------------------------------
%include "StuffRsbNasm.inc"
extern ASM_PFX(SmmInitHandler)
extern ASM_PFX(mRebasedFlag)
extern ASM_PFX(mSmmRelocationOriginalAddress)
global ASM_PFX(gPatchSmmCr3)
global ASM_PFX(gPatchSmmCr4)
global ASM_PFX(gPatchSmmCr0)
global ASM_PFX(gPatchSmmInitStack)
global ASM_PFX(gcSmiInitGdtr)
global ASM_PFX(gcSmmInitSize)
global ASM_PFX(gcSmmInitTemplate)
%define PROTECT_MODE_CS 0x8
%define PROTECT_MODE_DS 0x20
SECTION .data
NullSeg: DQ 0 ; reserved by architecture
CodeSeg32:
DW -1 ; LimitLow
DW 0 ; BaseLow
DB 0 ; BaseMid
DB 0x9b
DB 0xcf ; LimitHigh
DB 0 ; BaseHigh
ProtModeCodeSeg32:
DW -1 ; LimitLow
DW 0 ; BaseLow
DB 0 ; BaseMid
DB 0x9b
DB 0xcf ; LimitHigh
DB 0 ; BaseHigh
ProtModeSsSeg32:
DW -1 ; LimitLow
DW 0 ; BaseLow
DB 0 ; BaseMid
DB 0x93
DB 0xcf ; LimitHigh
DB 0 ; BaseHigh
DataSeg32:
DW -1 ; LimitLow
DW 0 ; BaseLow
DB 0 ; BaseMid
DB 0x93
DB 0xcf ; LimitHigh
DB 0 ; BaseHigh
CodeSeg16:
DW -1
DW 0
DB 0
DB 0x9b
DB 0x8f
DB 0
DataSeg16:
DW -1
DW 0
DB 0
DB 0x93
DB 0x8f
DB 0
CodeSeg64:
DW -1 ; LimitLow
DW 0 ; BaseLow
DB 0 ; BaseMid
DB 0x9b
DB 0xaf ; LimitHigh
DB 0 ; BaseHigh
GDT_SIZE equ $ - NullSeg
ASM_PFX(gcSmiInitGdtr):
DW GDT_SIZE - 1
DD NullSeg
SECTION .text
global ASM_PFX(SmmStartup)
BITS 16
ASM_PFX(SmmStartup):
mov eax, 0x80000001 ; read capability
cpuid
mov ebx, edx ; rdmsr will change edx. keep it in ebx.
and ebx, BIT20 ; extract NX capability bit
shr ebx, 9 ; shift bit to IA32_EFER.NXE[BIT11] position
mov eax, strict dword 0 ; source operand will be patched
ASM_PFX(gPatchSmmCr3):
mov cr3, eax
o32 lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))]
mov eax, strict dword 0 ; source operand will be patched
ASM_PFX(gPatchSmmCr4):
mov cr4, eax
mov ecx, 0xc0000080 ; IA32_EFER MSR
rdmsr
or eax, ebx ; set NXE bit if NX is available
wrmsr
mov eax, strict dword 0 ; source operand will be patched
ASM_PFX(gPatchSmmCr0):
mov di, PROTECT_MODE_DS
mov cr0, eax
jmp PROTECT_MODE_CS : dword @32bit
BITS 32
@32bit:
mov ds, edi
mov es, edi
mov fs, edi
mov gs, edi
mov ss, edi
mov esp, strict dword 0 ; source operand will be patched
ASM_PFX(gPatchSmmInitStack):
call ASM_PFX(SmmInitHandler)
StuffRsb32
rsm
BITS 16
ASM_PFX(gcSmmInitTemplate):
mov ebp, ASM_PFX(SmmStartup)
sub ebp, 0x30000
jmp ebp
ASM_PFX(gcSmmInitSize): DW $ - ASM_PFX(gcSmmInitTemplate)
BITS 32
global ASM_PFX(SmmRelocationSemaphoreComplete)
ASM_PFX(SmmRelocationSemaphoreComplete):
push eax
mov eax, [ASM_PFX(mRebasedFlag)]
mov byte [eax], 1
pop eax
jmp [ASM_PFX(mSmmRelocationOriginalAddress)]
global ASM_PFX(SmmInitFixupAddress)
ASM_PFX(SmmInitFixupAddress):
ret