--- /dev/null
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+; Abstract:\r
+;\r
+; Provide macro to push/pop registers in X64\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+;-----------------------------------------------------------------------------\r
+; Macro: PUSHA_64\r
+;\r
+; Description: Saves all registers on stack\r
+;\r
+; Input: None\r
+;\r
+; Output: None\r
+;-----------------------------------------------------------------------------\r
+%macro PUSHA_64 0\r
+ push r8\r
+ push r9\r
+ push r10\r
+ push r11\r
+ push r12\r
+ push r13\r
+ push r14\r
+ push r15\r
+ push rax\r
+ push rcx\r
+ push rdx\r
+ push rbx\r
+ push rsp\r
+ push rbp\r
+ push rsi\r
+ push rdi\r
+%endmacro\r
+\r
+;-----------------------------------------------------------------------------\r
+; Macro: POPA_64\r
+;\r
+; Description: Restores all registers from stack\r
+;\r
+; Input: None\r
+;\r
+; Output: None\r
+;-----------------------------------------------------------------------------\r
+%macro POPA_64 0\r
+ pop rdi\r
+ pop rsi\r
+ pop rbp\r
+ pop rsp\r
+ pop rbx\r
+ pop rdx\r
+ pop rcx\r
+ pop rax\r
+ pop r15\r
+ pop r14\r
+ pop r13\r
+ pop r12\r
+ pop r11\r
+ pop r10\r
+ pop r9\r
+ pop r8\r
+%endmacro\r
+\r
--- /dev/null
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+; Abstract:\r
+;\r
+; Switch the stack from temporary memory to permanent memory.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+ SECTION .text\r
+\r
+%include "PushPopRegsNasm.inc"\r
+\r
+extern ASM_PFX(SwapStack)\r
+\r
+;------------------------------------------------------------------------------\r
+; UINT32\r
+; EFIAPI\r
+; Pei2LoaderSwitchStack (\r
+; VOID\r
+; )\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(Pei2LoaderSwitchStack)\r
+ASM_PFX(Pei2LoaderSwitchStack):\r
+ xor rax, rax\r
+ jmp ASM_PFX(FspSwitchStack)\r
+\r
+;------------------------------------------------------------------------------\r
+; UINT32\r
+; EFIAPI\r
+; Loader2PeiSwitchStack (\r
+; VOID\r
+; )\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(Loader2PeiSwitchStack)\r
+ASM_PFX(Loader2PeiSwitchStack):\r
+ jmp ASM_PFX(FspSwitchStack)\r
+\r
+;------------------------------------------------------------------------------\r
+; UINT32\r
+; EFIAPI\r
+; FspSwitchStack (\r
+; VOID\r
+; )\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(FspSwitchStack)\r
+ASM_PFX(FspSwitchStack):\r
+ ; Save current contexts\r
+ push rdx ; ApiParam2\r
+ push rcx ; ApiParam1\r
+ push rax ; FspInfoHeader\r
+ pushfq\r
+ cli\r
+ PUSHA_64\r
+ sub rsp, 16\r
+ sidt [rsp]\r
+\r
+ ; Load new stack\r
+ mov rcx, rsp\r
+ call ASM_PFX(SwapStack)\r
+ mov rsp, rax\r
+\r
+ ; Restore previous contexts\r
+ lidt [rsp]\r
+ add rsp, 16\r
+ POPA_64\r
+ popfq\r
+ add rsp, 24 ; FspInfoHeader + ApiParam[2]\r
+ ret\r
+\r