The IA32 version of "SmmInit.nasm" does not need "gSmmJmpAddr" at all (its
PiSmmCpuSmmInitFixupAddress() variant doesn't do anything either). We can
simply use the NASM syntax for the following Mixed-Size Jump:
> jmp PROTECT_MODE_CS : dword @32bit
The generated object code for the instruction is unchanged:
>
00000182 66EA5A0000000800 jmp dword 0x8:0x5a
(The NASM manual explains that putting the DWORD prefix after the colon
":" reflects the intent better, since it is the offset that is a DWORD.
Thus, that's what I used. However, both syntaxes are interchangeable,
hence the ndisasm output.)
The X64 version of "SmmInit.nasm" appears to require "gSmmJmpAddr";
however that's accidental, not inherent:
- Bring LONG_MODE_CODE_SEGMENT from
"UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h" to "SmmInit.nasm" as
LONG_MODE_CS, same as PROTECT_MODE_CODE_SEGMENT was brought to the IA32
version as PROTECT_MODE_CS earlier.
- Apply the NASM-native Mixed-Size Jump syntax again, but jump to the
fixed zero offset in LONG_MODE_CS. This will produce no relocation
record at all. Add a label after the instruction.
- Modify PiSmmCpuSmmInitFixupAddress() to patch the jump target backwards
from the label. Because we modify the DWORD offset with a DWORD access,
the segment selector is unharmed in the instruction, and we need not set
it from PiCpuSmmEntry().
According to "objdump --reloc", the X64 version undergoes only the
following relocations, after this patch:
> RELOCATION RECORDS FOR [.text]:
> OFFSET TYPE VALUE
>
0000000000000095 R_X86_64_PC32 SmmInitHandler-0x0000000000000004
>
00000000000000e0 R_X86_64_PC32 mRebasedFlag-0x0000000000000004
>
00000000000000ea R_X86_64_PC32 mSmmRelocationOriginalAddress-0x0000000000000004
Therefore the patch does not regress
<https://bugzilla.tianocore.org/show_bug.cgi?id=849> ("Enable XCODE5 tool
chain for UefiCpuPkg with nasm source code").
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>
global ASM_PFX(gPatchSmmCr3)\r
global ASM_PFX(gPatchSmmCr4)\r
global ASM_PFX(gPatchSmmCr0)\r
-global ASM_PFX(gSmmJmpAddr)\r
global ASM_PFX(gSmmInitStack)\r
global ASM_PFX(gcSmiInitGdtr)\r
global ASM_PFX(gcSmmInitSize)\r
ASM_PFX(gPatchSmmCr0):\r
mov di, PROTECT_MODE_DS\r
mov cr0, eax\r
- DB 0x66, 0xea ; jmp far [ptr48]\r
-ASM_PFX(gSmmJmpAddr):\r
- DD @32bit\r
- DW PROTECT_MODE_CS\r
+ jmp PROTECT_MODE_CS : dword @32bit\r
\r
BITS 32\r
@32bit:\r
EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT\r
);\r
\r
- //\r
- // Fix segment address of the long-mode-switch jump\r
- //\r
- if (sizeof (UINTN) == sizeof (UINT64)) {\r
- gSmmJmpAddr.Segment = LONG_MODE_CODE_SEGMENT;\r
- }\r
-\r
//\r
// Find out SMRR Base and SMRR Size\r
//\r
IN CONST VOID *Buffer\r
);\r
\r
-//\r
-//\r
-//\r
-typedef struct {\r
- UINT32 Offset;\r
- UINT16 Segment;\r
- UINT16 Reserved;\r
-} IA32_FAR_ADDRESS;\r
-\r
-extern IA32_FAR_ADDRESS gSmmJmpAddr;\r
-\r
extern CONST UINT8 gcSmmInitTemplate[];\r
extern CONST UINT16 gcSmmInitSize;\r
X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr0;\r
global ASM_PFX(gPatchSmmCr3)\r
global ASM_PFX(gPatchSmmCr4)\r
global ASM_PFX(gPatchSmmCr0)\r
-global ASM_PFX(gSmmJmpAddr)\r
global ASM_PFX(gSmmInitStack)\r
global ASM_PFX(gcSmiInitGdtr)\r
global ASM_PFX(gcSmmInitSize)\r
global ASM_PFX(mRebasedFlagAddr32)\r
global ASM_PFX(mSmmRelocationOriginalAddressPtr32)\r
\r
+%define LONG_MODE_CS 0x38\r
+\r
DEFAULT REL\r
SECTION .text\r
\r
mov eax, strict dword 0 ; source operand will be patched\r
ASM_PFX(gPatchSmmCr0):\r
mov cr0, eax ; enable protected mode & paging\r
- DB 0x66, 0xea ; far jmp to long mode\r
-ASM_PFX(gSmmJmpAddr): DQ 0;@LongMode\r
+ jmp LONG_MODE_CS : dword 0 ; offset will be patched to @LongMode\r
+@PatchLongModeOffset:\r
\r
BITS 64\r
@LongMode: ; long-mode starts here\r
global ASM_PFX(PiSmmCpuSmmInitFixupAddress)\r
ASM_PFX(PiSmmCpuSmmInitFixupAddress):\r
lea rax, [@LongMode]\r
- lea rcx, [ASM_PFX(gSmmJmpAddr)]\r
- mov qword [rcx], rax\r
+ lea rcx, [@PatchLongModeOffset - 6]\r
+ mov dword [rcx], eax\r
\r
lea rax, [ASM_PFX(SmmStartup)]\r
lea rcx, [@L1]\r