audk/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm

104 lines
3.1 KiB
NASM
Raw Normal View History

;------------------------------------------------------------------------------ ;
; Copyright (c) 2016 - 2018, 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.
;
; Module Name:
;
; SmmInit.nasm
;
; Abstract:
;
; Functions for relocating SMBASE's for all processors
;
;-------------------------------------------------------------------------------
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(gSmmJmpAddr)
global ASM_PFX(gSmmInitStack)
global ASM_PFX(gcSmiInitGdtr)
global ASM_PFX(gcSmmInitSize)
global ASM_PFX(gcSmmInitTemplate)
%define PROTECT_MODE_CS 0x8
%define PROTECT_MODE_DS 0x20
SECTION .text
ASM_PFX(gcSmiInitGdtr):
DW 0
DQ 0
global ASM_PFX(SmmStartup)
UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() The SmmStartup() executes in SMM, which is very similar to real mode. Add "BITS 16" before it and "BITS 32" after it (just before the @32bit label). Remove the manual 0x66 operand-size override prefixes, for selecting 32-bit operands -- the sizes of our operands trigger NASM to insert the prefixes automatically in almost every spot. The one place where we have to add it back manually is the LGDT instruction. (The 0x67 address-size override prefix is also auto-generated.) This patch causes NASM to generate byte-identical object code (determined by disassembling both the pre-patch and post-patch versions, and comparing the listings), except: > @@ -158,7 +158,7 @@ > 00000142 6689D3 mov ebx,edx > 00000145 66B800000000 mov eax,0x0 > 0000014B 0F22D8 mov cr3,eax > -0000014E 67662E0F0155F6 o32 lgdt [cs:ebp-0xa] > +0000014E 2E66670F0155F6 o32 lgdt [cs:ebp-0xa] > 00000155 66B800000000 mov eax,0x0 > 0000015B 0F22E0 mov cr4,eax > 0000015E 66B9800000C0 mov ecx,0xc0000080 The only difference is the prefix list order, it changes from: - 0x67, 0x66, 0x2E to - 0x2E, 0x66, 0x67 (0x2E is "CS segment override"). Cc: Eric Dong <eric.dong@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@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: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
2018-01-30 14:43:28 +01:00
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
UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() The SmmStartup() executes in SMM, which is very similar to real mode. Add "BITS 16" before it and "BITS 32" after it (just before the @32bit label). Remove the manual 0x66 operand-size override prefixes, for selecting 32-bit operands -- the sizes of our operands trigger NASM to insert the prefixes automatically in almost every spot. The one place where we have to add it back manually is the LGDT instruction. (The 0x67 address-size override prefix is also auto-generated.) This patch causes NASM to generate byte-identical object code (determined by disassembling both the pre-patch and post-patch versions, and comparing the listings), except: > @@ -158,7 +158,7 @@ > 00000142 6689D3 mov ebx,edx > 00000145 66B800000000 mov eax,0x0 > 0000014B 0F22D8 mov cr3,eax > -0000014E 67662E0F0155F6 o32 lgdt [cs:ebp-0xa] > +0000014E 2E66670F0155F6 o32 lgdt [cs:ebp-0xa] > 00000155 66B800000000 mov eax,0x0 > 0000015B 0F22E0 mov cr4,eax > 0000015E 66B9800000C0 mov ecx,0xc0000080 The only difference is the prefix list order, it changes from: - 0x67, 0x66, 0x2E to - 0x2E, 0x66, 0x67 (0x2E is "CS segment override"). Cc: Eric Dong <eric.dong@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@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: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
2018-01-30 14:43:28 +01:00
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):
UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() The SmmStartup() executes in SMM, which is very similar to real mode. Add "BITS 16" before it and "BITS 32" after it (just before the @32bit label). Remove the manual 0x66 operand-size override prefixes, for selecting 32-bit operands -- the sizes of our operands trigger NASM to insert the prefixes automatically in almost every spot. The one place where we have to add it back manually is the LGDT instruction. (The 0x67 address-size override prefix is also auto-generated.) This patch causes NASM to generate byte-identical object code (determined by disassembling both the pre-patch and post-patch versions, and comparing the listings), except: > @@ -158,7 +158,7 @@ > 00000142 6689D3 mov ebx,edx > 00000145 66B800000000 mov eax,0x0 > 0000014B 0F22D8 mov cr3,eax > -0000014E 67662E0F0155F6 o32 lgdt [cs:ebp-0xa] > +0000014E 2E66670F0155F6 o32 lgdt [cs:ebp-0xa] > 00000155 66B800000000 mov eax,0x0 > 0000015B 0F22E0 mov cr4,eax > 0000015E 66B9800000C0 mov ecx,0xc0000080 The only difference is the prefix list order, it changes from: - 0x67, 0x66, 0x2E to - 0x2E, 0x66, 0x67 (0x2E is "CS segment override"). Cc: Eric Dong <eric.dong@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@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: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
2018-01-30 14:43:28 +01:00
mov di, PROTECT_MODE_DS
mov cr0, eax
DB 0x66, 0xea ; jmp far [ptr48]
ASM_PFX(gSmmJmpAddr):
DD @32bit
DW PROTECT_MODE_CS
UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() The SmmStartup() executes in SMM, which is very similar to real mode. Add "BITS 16" before it and "BITS 32" after it (just before the @32bit label). Remove the manual 0x66 operand-size override prefixes, for selecting 32-bit operands -- the sizes of our operands trigger NASM to insert the prefixes automatically in almost every spot. The one place where we have to add it back manually is the LGDT instruction. (The 0x67 address-size override prefix is also auto-generated.) This patch causes NASM to generate byte-identical object code (determined by disassembling both the pre-patch and post-patch versions, and comparing the listings), except: > @@ -158,7 +158,7 @@ > 00000142 6689D3 mov ebx,edx > 00000145 66B800000000 mov eax,0x0 > 0000014B 0F22D8 mov cr3,eax > -0000014E 67662E0F0155F6 o32 lgdt [cs:ebp-0xa] > +0000014E 2E66670F0155F6 o32 lgdt [cs:ebp-0xa] > 00000155 66B800000000 mov eax,0x0 > 0000015B 0F22E0 mov cr4,eax > 0000015E 66B9800000C0 mov ecx,0xc0000080 The only difference is the prefix list order, it changes from: - 0x67, 0x66, 0x2E to - 0x2E, 0x66, 0x67 (0x2E is "CS segment override"). Cc: Eric Dong <eric.dong@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@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: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
2018-01-30 14:43:28 +01:00
BITS 32
@32bit:
mov ds, edi
mov es, edi
mov fs, edi
mov gs, edi
mov ss, edi
DB 0xbc ; mov esp, imm32
ASM_PFX(gSmmInitStack): DD 0
call ASM_PFX(SmmInitHandler)
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(PiSmmCpuSmmInitFixupAddress)
ASM_PFX(PiSmmCpuSmmInitFixupAddress):
ret