From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web09.26060.1652685265461479831 for ; Mon, 16 May 2022 00:14:27 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=NqtNPzT9; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: ray.ni@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652685266; x=1684221266; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pILcp+1NZF5lv8ysIpeB9EkVvBRpVx7gczlhxQIGSrE=; b=NqtNPzT9gB3T+CznLm+8a6FTS7brUtm5T2nFtzocvHgTpsOZ02YRUp2d QuLEafi1DvGkum5ALwlpaNThNEDyCrBaOV7iLQxc5d475fB8SI77MdZ4T NsF4Mg7SKgPurWqqha1tLvbe4hoTTsP2eDnEKPL7YzpC5cP6OJhbg9Gzk W+4+SkfuctRTZOfooX2JMC4/mNuu8RJ5JMZY0LecbVCd0ud28+Ky/qJNb gB2MErM0W2zOmF3U3P5+hOKPMEsa3YoMgx/+0zgQ0e1d8auzuFLIcIDXZ dfUuP1U+WkQdEFT8bQJCIuknCho4Ikwbg2ShJfAYvwoGfg01YLDJ9pyH9 g==; X-IronPort-AV: E=McAfee;i="6400,9594,10348"; a="270451779" X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="270451779" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 May 2022 00:14:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,229,1647327600"; d="scan'208";a="555129038" Received: from shwdeopenlab706.ccr.corp.intel.com ([10.239.183.102]) by orsmga002.jf.intel.com with ESMTP; 16 May 2022 00:14:22 -0700 From: "Ni, Ray" To: devel@edk2.groups.io Cc: Eric Dong , Rahul Kumar , Michael Roth , James Bottomley , Min Xu , Jiewen Yao , Tom Lendacky , Jordan Justen , Ard Biesheuvel , Erdem Aktas , Gerd Hoffmann Subject: [PATCH v3 3/5] MpInitLib: Put SEV logic in separate file Date: Mon, 16 May 2022 15:14:10 +0800 Message-Id: <20220516071412.359-4-ray.ni@intel.com> X-Mailer: git-send-email 2.35.1.windows.2 In-Reply-To: <20220516071412.359-1-ray.ni@intel.com> References: <20220516071412.359-1-ray.ni@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable The patch does several simplifications: 1. Treat SwitchToRealProc as part of RendezvousFunnelProc. So the common logic in MpLib.c doesn't need to be aware of SwitchToRealProc. As a result, SwitchToRealSize/Offset are removed from MP_ASSEMBLY_ADDRESS_MAP. 2. Move SwitchToRealProc to AmdSev.nasm. All other assembly code in AmdSev.nasm is called through OneTimeCall. Signed-off-by: Ray Ni Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Michael Roth Cc: James Bottomley Cc: Min Xu Cc: Jiewen Yao Cc: Tom Lendacky Cc: Jordan Justen Cc: Ard Biesheuvel Cc: Erdem Aktas Cc: Gerd Hoffmann --- .../Library/MpInitLib/Ia32/MpFuncs.nasm | 5 +- UefiCpuPkg/Library/MpInitLib/MpEqu.inc | 4 +- UefiCpuPkg/Library/MpInitLib/MpLib.c | 13 +- UefiCpuPkg/Library/MpInitLib/MpLib.h | 4 +- UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm | 148 ++++++++++++++++ UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 159 +----------------- 6 files changed, 161 insertions(+), 172 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Li= brary/MpInitLib/Ia32/MpFuncs.nasm index 8981c32722..28301bb8f0 100644 --- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm +++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm @@ -199,7 +199,6 @@ CProcedureInvoke: call eax ; Invoke C function=0D =0D jmp $ ; Never reach here=0D -RendezvousFunnelProcEnd:=0D =0D ;-------------------------------------------------------------------------= ------------=0D ;SwitchToRealProc procedure follows.=0D @@ -209,6 +208,8 @@ SwitchToRealProcStart: jmp $ ; Never reach here=0D SwitchToRealProcEnd:=0D =0D +RendezvousFunnelProcEnd:=0D +=0D ;-------------------------------------------------------------------------= ------------=0D ; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfAp= Stack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);=0D ;=0D @@ -258,8 +259,6 @@ ASM_PFX(AsmGetAddressMap): mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddr= ess], AsmRelocateApLoopStart=0D mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize= ], AsmRelocateApLoopEnd - AsmRelocateApLoopStart=0D mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset],= Flat32Start - RendezvousFunnelProcStart=0D - mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], Swi= tchToRealProcEnd - SwitchToRealProcStart=0D - mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], S= witchToRealProcStart - RendezvousFunnelProcStart=0D mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset= ], SwitchToRealProcStart - Flat32Start=0D mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOf= fset], 0=0D mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSi= ze], 0=0D diff --git a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc b/UefiCpuPkg/Library/Mp= InitLib/MpEqu.inc index aba53f5720..1cc071cf7b 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc +++ b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc @@ -1,5 +1,5 @@ ;-------------------------------------------------------------------------= ----- ;=0D -; Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
=0D +; Copyright (c) 2015 - 2022, Intel Corporation. All rights reserved.
=0D ; SPDX-License-Identifier: BSD-2-Clause-Patent=0D ;=0D ; Module Name:=0D @@ -27,8 +27,6 @@ struc MP_ASSEMBLY_ADDRESS_MAP .RelocateApLoopFuncAddress CTYPE_UINTN 1=0D .RelocateApLoopFuncSize CTYPE_UINTN 1=0D .ModeTransitionOffset CTYPE_UINTN 1=0D - .SwitchToRealSize CTYPE_UINTN 1=0D - .SwitchToRealOffset CTYPE_UINTN 1=0D .SwitchToRealNoNxOffset CTYPE_UINTN 1=0D .SwitchToRealPM16ModeOffset CTYPE_UINTN 1=0D .SwitchToRealPM16ModeSize CTYPE_UINTN 1=0D diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpIn= itLib/MpLib.c index d761bdc487..aa0eb9a70b 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -936,8 +936,7 @@ FillExchangeInfoData ( // EfiBootServicesCode to avoid page fault if NX memory protection is en= abled.=0D //=0D if (CpuMpData->WakeupBufferHigh !=3D 0) {=0D - Size =3D CpuMpData->AddressMap.RendezvousFunnelSize +=0D - CpuMpData->AddressMap.SwitchToRealSize -=0D + Size =3D CpuMpData->AddressMap.RendezvousFunnelSize -=0D CpuMpData->AddressMap.ModeTransitionOffset;=0D CopyMem (=0D (VOID *)CpuMpData->WakeupBufferHigh,=0D @@ -991,8 +990,7 @@ BackupAndPrepareWakeupBuffer ( CopyMem (=0D (VOID *)CpuMpData->WakeupBuffer,=0D (VOID *)CpuMpData->AddressMap.RendezvousFunnelAddress,=0D - CpuMpData->AddressMap.RendezvousFunnelSize +=0D - CpuMpData->AddressMap.SwitchToRealSize=0D + CpuMpData->AddressMap.RendezvousFunnelSize=0D );=0D }=0D =0D @@ -1029,7 +1027,6 @@ GetApResetVectorSize ( UINTN Size;=0D =0D Size =3D AddressMap->RendezvousFunnelSize +=0D - AddressMap->SwitchToRealSize +=0D sizeof (MP_CPU_EXCHANGE_INFO);=0D =0D return Size;=0D @@ -1054,11 +1051,9 @@ AllocateResetVector ( CpuMpData->WakeupBuffer =3D GetWakeupBuffer (ApResetVectorSize);= =0D CpuMpData->MpCpuExchangeInfo =3D (MP_CPU_EXCHANGE_INFO *)(UINTN)=0D (CpuMpData->WakeupBuffer +=0D - CpuMpData->AddressMap.RendezvousFunnel= Size +=0D - CpuMpData->AddressMap.SwitchToRealSize= );=0D + CpuMpData->AddressMap.RendezvousFunnel= Size);=0D CpuMpData->WakeupBufferHigh =3D AllocateCodeBuffer (=0D - CpuMpData->AddressMap.RendezvousFunnel= Size +=0D - CpuMpData->AddressMap.SwitchToRealSize= -=0D + CpuMpData->AddressMap.RendezvousFunnel= Size -=0D CpuMpData->AddressMap.ModeTransitionOf= fset=0D );=0D //=0D diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index 59ab960897..974fb76019 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -1,7 +1,7 @@ /** @file=0D Common header file for MP Initialize Library.=0D =0D - Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.
=0D + Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.
=0D Copyright (c) 2020, AMD Inc. All rights reserved.
=0D =0D SPDX-License-Identifier: BSD-2-Clause-Patent=0D @@ -181,8 +181,6 @@ typedef struct { UINT8 *RelocateApLoopFuncAddress;=0D UINTN RelocateApLoopFuncSize;=0D UINTN ModeTransitionOffset;=0D - UINTN SwitchToRealSize;=0D - UINTN SwitchToRealOffset;=0D UINTN SwitchToRealNoNxOffset;=0D UINTN SwitchToRealPM16ModeOffset;=0D UINTN SwitchToRealPM16ModeSize;=0D diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm b/UefiCpuPkg/Libr= ary/MpInitLib/X64/AmdSev.nasm index 8bb1161fa0..7c2469f9c5 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm +++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm @@ -198,3 +198,151 @@ RestoreGhcb: =0D SevEsGetApicIdExit:=0D OneTimeCallRet SevEsGetApicId=0D +=0D +=0D +;-------------------------------------------------------------------------= ------------=0D +;SwitchToRealProc procedure follows.=0D +;ALSO THIS PROCEDURE IS EXECUTED BY APs TRANSITIONING TO 16 BIT MODE. HENC= E THIS PROC=0D +;IS IN MACHINE CODE.=0D +; SwitchToRealProc (UINTN BufferStart, UINT16 Code16, UINT16 Code32, UINT= N StackStart)=0D +; rcx - Buffer Start=0D +; rdx - Code16 Selector Offset=0D +; r8 - Code32 Selector Offset=0D +; r9 - Stack Start=0D +;-------------------------------------------------------------------------= ------------=0D +SwitchToRealProcStart:=0D +BITS 64=0D + cli=0D +=0D + ;=0D + ; Get RDX reset value before changing stacks since the=0D + ; new stack won't be able to accomodate a #VC exception.=0D + ;=0D + push rax=0D + push rbx=0D + push rcx=0D + push rdx=0D +=0D + mov rax, 1=0D + cpuid=0D + mov rsi, rax ; Save off the reset value for = RDX=0D +=0D + pop rdx=0D + pop rcx=0D + pop rbx=0D + pop rax=0D +=0D + ;=0D + ; Establish stack below 1MB=0D + ;=0D + mov rsp, r9=0D +=0D + ;=0D + ; Push ultimate Reset Vector onto the stack=0D + ;=0D + mov rax, rcx=0D + shr rax, 4=0D + push word 0x0002 ; RFLAGS=0D + push ax ; CS=0D + push word 0x0000 ; RIP=0D + push word 0x0000 ; For alignment, will be discar= ded=0D +=0D + ;=0D + ; Get address of "16-bit operand size" label=0D + ;=0D + lea rbx, [PM16Mode]=0D +=0D + ;=0D + ; Push addresses used to change to compatibility mode=0D + ;=0D + lea rax, [CompatMode]=0D + push r8=0D + push rax=0D +=0D + ;=0D + ; Clear R8 - R15, for reset, before going into 32-bit mode=0D + ;=0D + xor r8, r8=0D + xor r9, r9=0D + xor r10, r10=0D + xor r11, r11=0D + xor r12, r12=0D + xor r13, r13=0D + xor r14, r14=0D + xor r15, r15=0D +=0D + ;=0D + ; Far return into 32-bit mode=0D + ;=0D + retfq=0D +=0D +BITS 32=0D +CompatMode:=0D + ;=0D + ; Set up stack to prepare for exiting protected mode=0D + ;=0D + push edx ; Code16 CS=0D + push ebx ; PM16Mode label address=0D +=0D + ;=0D + ; Disable paging=0D + ;=0D + mov eax, cr0 ; Read CR0=0D + btr eax, 31 ; Set PG=3D0=0D + mov cr0, eax ; Write CR0=0D +=0D + ;=0D + ; Disable long mode=0D + ;=0D + mov ecx, 0c0000080h ; EFER MSR number=0D + rdmsr ; Read EFER=0D + btr eax, 8 ; Set LME=3D0=0D + wrmsr ; Write EFER=0D +=0D + ;=0D + ; Disable PAE=0D + ;=0D + mov eax, cr4 ; Read CR4=0D + btr eax, 5 ; Set PAE=3D0=0D + mov cr4, eax ; Write CR4=0D +=0D + mov edx, esi ; Restore RDX reset value=0D +=0D + ;=0D + ; Switch to 16-bit operand size=0D + ;=0D + retf=0D +=0D +BITS 16=0D + ;=0D + ; At entry to this label=0D + ; - RDX will have its reset value=0D + ; - On the top of the stack=0D + ; - Alignment data (two bytes) to be discarded=0D + ; - IP for Real Mode (two bytes)=0D + ; - CS for Real Mode (two bytes)=0D + ;=0D + ; This label is also used with AsmRelocateApLoop. During MP finalizati= on,=0D + ; the code from PM16Mode to SwitchToRealProcEnd is copied to the start= of=0D + ; the WakeupBuffer, allowing a parked AP to be booted by an OS.=0D + ;=0D +PM16Mode:=0D + mov eax, cr0 ; Read CR0=0D + btr eax, 0 ; Set PE=3D0=0D + mov cr0, eax ; Write CR0=0D +=0D + pop ax ; Discard alignment data=0D +=0D + ;=0D + ; Clear registers (except RDX and RSP) before going into 16-bit mode=0D + ;=0D + xor eax, eax=0D + xor ebx, ebx=0D + xor ecx, ecx=0D + xor esi, esi=0D + xor edi, edi=0D + xor ebp, ebp=0D +=0D + iret=0D +=0D +SwitchToRealProcEnd:=0D diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Lib= rary/MpInitLib/X64/MpFuncs.nasm index d7e0e1fabd..1daaa72b1e 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm +++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm @@ -152,11 +152,6 @@ SkipEnable5LevelPaging: =0D BITS 64=0D =0D -;=0D -; Required for the AMD SEV helper functions=0D -;=0D -%include "AmdSev.nasm"=0D -=0D LongModeStart:=0D mov esi, ebx=0D lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (InitFlag)]=0D @@ -265,154 +260,12 @@ CProcedureInvoke: add rsp, 20h=0D jmp $ ; Should never reach here=0D =0D -RendezvousFunnelProcEnd:=0D -=0D -;-------------------------------------------------------------------------= ------------=0D -;SwitchToRealProc procedure follows.=0D -;ALSO THIS PROCEDURE IS EXECUTED BY APs TRANSITIONING TO 16 BIT MODE. HENC= E THIS PROC=0D -;IS IN MACHINE CODE.=0D -; SwitchToRealProc (UINTN BufferStart, UINT16 Code16, UINT16 Code32, UINT= N StackStart)=0D -; rcx - Buffer Start=0D -; rdx - Code16 Selector Offset=0D -; r8 - Code32 Selector Offset=0D -; r9 - Stack Start=0D -;-------------------------------------------------------------------------= ------------=0D -SwitchToRealProcStart:=0D -BITS 64=0D - cli=0D -=0D - ;=0D - ; Get RDX reset value before changing stacks since the=0D - ; new stack won't be able to accomodate a #VC exception.=0D - ;=0D - push rax=0D - push rbx=0D - push rcx=0D - push rdx=0D -=0D - mov rax, 1=0D - cpuid=0D - mov rsi, rax ; Save off the reset value for = RDX=0D -=0D - pop rdx=0D - pop rcx=0D - pop rbx=0D - pop rax=0D -=0D - ;=0D - ; Establish stack below 1MB=0D - ;=0D - mov rsp, r9=0D -=0D - ;=0D - ; Push ultimate Reset Vector onto the stack=0D - ;=0D - mov rax, rcx=0D - shr rax, 4=0D - push word 0x0002 ; RFLAGS=0D - push ax ; CS=0D - push word 0x0000 ; RIP=0D - push word 0x0000 ; For alignment, will be discar= ded=0D -=0D - ;=0D - ; Get address of "16-bit operand size" label=0D - ;=0D - lea rbx, [PM16Mode]=0D -=0D - ;=0D - ; Push addresses used to change to compatibility mode=0D - ;=0D - lea rax, [CompatMode]=0D - push r8=0D - push rax=0D -=0D - ;=0D - ; Clear R8 - R15, for reset, before going into 32-bit mode=0D - ;=0D - xor r8, r8=0D - xor r9, r9=0D - xor r10, r10=0D - xor r11, r11=0D - xor r12, r12=0D - xor r13, r13=0D - xor r14, r14=0D - xor r15, r15=0D -=0D - ;=0D - ; Far return into 32-bit mode=0D - ;=0D - retfq=0D -=0D -BITS 32=0D -CompatMode:=0D - ;=0D - ; Set up stack to prepare for exiting protected mode=0D - ;=0D - push edx ; Code16 CS=0D - push ebx ; PM16Mode label address=0D -=0D - ;=0D - ; Disable paging=0D - ;=0D - mov eax, cr0 ; Read CR0=0D - btr eax, 31 ; Set PG=3D0=0D - mov cr0, eax ; Write CR0=0D -=0D - ;=0D - ; Disable long mode=0D - ;=0D - mov ecx, 0c0000080h ; EFER MSR number=0D - rdmsr ; Read EFER=0D - btr eax, 8 ; Set LME=3D0=0D - wrmsr ; Write EFER=0D -=0D - ;=0D - ; Disable PAE=0D - ;=0D - mov eax, cr4 ; Read CR4=0D - btr eax, 5 ; Set PAE=3D0=0D - mov cr4, eax ; Write CR4=0D -=0D - mov edx, esi ; Restore RDX reset value=0D -=0D - ;=0D - ; Switch to 16-bit operand size=0D - ;=0D - retf=0D -=0D -BITS 16=0D - ;=0D - ; At entry to this label=0D - ; - RDX will have its reset value=0D - ; - On the top of the stack=0D - ; - Alignment data (two bytes) to be discarded=0D - ; - IP for Real Mode (two bytes)=0D - ; - CS for Real Mode (two bytes)=0D - ;=0D - ; This label is also used with AsmRelocateApLoop. During MP finalizati= on,=0D - ; the code from PM16Mode to SwitchToRealProcEnd is copied to the start= of=0D - ; the WakeupBuffer, allowing a parked AP to be booted by an OS.=0D - ;=0D -PM16Mode:=0D - mov eax, cr0 ; Read CR0=0D - btr eax, 0 ; Set PE=3D0=0D - mov cr0, eax ; Write CR0=0D -=0D - pop ax ; Discard alignment data=0D -=0D - ;=0D - ; Clear registers (except RDX and RSP) before going into 16-bit mode=0D - ;=0D - xor eax, eax=0D - xor ebx, ebx=0D - xor ecx, ecx=0D - xor esi, esi=0D - xor edi, edi=0D - xor ebp, ebp=0D -=0D - iret=0D +;=0D +; Required for the AMD SEV helper functions=0D +;=0D +%include "AmdSev.nasm"=0D =0D -SwitchToRealProcEnd:=0D +RendezvousFunnelProcEnd:=0D =0D ;-------------------------------------------------------------------------= ------------=0D ; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfAp= Stack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);=0D @@ -596,8 +449,6 @@ ASM_PFX(AsmGetAddressMap): mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddr= ess], rax=0D mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize= ], AsmRelocateApLoopEnd - AsmRelocateApLoopStart=0D mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset],= Flat32Start - RendezvousFunnelProcStart=0D - mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], Swi= tchToRealProcEnd - SwitchToRealProcStart=0D - mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], S= witchToRealProcStart - RendezvousFunnelProcStart=0D mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset= ], SwitchToRealProcStart - Flat32Start=0D mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOf= fset], PM16Mode - RendezvousFunnelProcStart=0D mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSi= ze], SwitchToRealProcEnd - PM16Mode=0D --=20 2.35.1.windows.2