;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
;IS IN MACHINE CODE.\r
;-------------------------------------------------------------------------------------\r
-global ASM_PFX(RendezvousFunnelProc)\r
-ASM_PFX(RendezvousFunnelProc):\r
RendezvousFunnelProcStart:\r
; At this point CS = 0x(vv00) and ip= 0x0.\r
; Save BIST information to ebp firstly\r
\r
BITS 64\r
\r
-;\r
-; Required for the AMD SEV helper functions\r
-;\r
-%include "AmdSev.nasm"\r
-\r
LongModeStart:\r
mov esi, ebx\r
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (InitFlag)]\r
add rsp, 20h\r
jmp $ ; Should never reach here\r
\r
-RendezvousFunnelProcEnd:\r
-\r
-;-------------------------------------------------------------------------------------\r
-;SwitchToRealProc procedure follows.\r
-;ALSO THIS PROCEDURE IS EXECUTED BY APs TRANSITIONING TO 16 BIT MODE. HENCE THIS PROC\r
-;IS IN MACHINE CODE.\r
-; SwitchToRealProc (UINTN BufferStart, UINT16 Code16, UINT16 Code32, UINTN StackStart)\r
-; rcx - Buffer Start\r
-; rdx - Code16 Selector Offset\r
-; r8 - Code32 Selector Offset\r
-; r9 - Stack Start\r
-;-------------------------------------------------------------------------------------\r
-global ASM_PFX(SwitchToRealProc)\r
-ASM_PFX(SwitchToRealProc):\r
-SwitchToRealProcStart:\r
-BITS 64\r
- cli\r
-\r
- ;\r
- ; Get RDX reset value before changing stacks since the\r
- ; new stack won't be able to accomodate a #VC exception.\r
- ;\r
- push rax\r
- push rbx\r
- push rcx\r
- push rdx\r
-\r
- mov rax, 1\r
- cpuid\r
- mov rsi, rax ; Save off the reset value for RDX\r
-\r
- pop rdx\r
- pop rcx\r
- pop rbx\r
- pop rax\r
-\r
- ;\r
- ; Establish stack below 1MB\r
- ;\r
- mov rsp, r9\r
-\r
- ;\r
- ; Push ultimate Reset Vector onto the stack\r
- ;\r
- mov rax, rcx\r
- shr rax, 4\r
- push word 0x0002 ; RFLAGS\r
- push ax ; CS\r
- push word 0x0000 ; RIP\r
- push word 0x0000 ; For alignment, will be discarded\r
-\r
- ;\r
- ; Get address of "16-bit operand size" label\r
- ;\r
- lea rbx, [PM16Mode]\r
-\r
- ;\r
- ; Push addresses used to change to compatibility mode\r
- ;\r
- lea rax, [CompatMode]\r
- push r8\r
- push rax\r
-\r
- ;\r
- ; Clear R8 - R15, for reset, before going into 32-bit mode\r
- ;\r
- xor r8, r8\r
- xor r9, r9\r
- xor r10, r10\r
- xor r11, r11\r
- xor r12, r12\r
- xor r13, r13\r
- xor r14, r14\r
- xor r15, r15\r
-\r
- ;\r
- ; Far return into 32-bit mode\r
- ;\r
- retfq\r
-\r
-BITS 32\r
-CompatMode:\r
- ;\r
- ; Set up stack to prepare for exiting protected mode\r
- ;\r
- push edx ; Code16 CS\r
- push ebx ; PM16Mode label address\r
-\r
- ;\r
- ; Disable paging\r
- ;\r
- mov eax, cr0 ; Read CR0\r
- btr eax, 31 ; Set PG=0\r
- mov cr0, eax ; Write CR0\r
-\r
- ;\r
- ; Disable long mode\r
- ;\r
- mov ecx, 0c0000080h ; EFER MSR number\r
- rdmsr ; Read EFER\r
- btr eax, 8 ; Set LME=0\r
- wrmsr ; Write EFER\r
-\r
- ;\r
- ; Disable PAE\r
- ;\r
- mov eax, cr4 ; Read CR4\r
- btr eax, 5 ; Set PAE=0\r
- mov cr4, eax ; Write CR4\r
-\r
- mov edx, esi ; Restore RDX reset value\r
-\r
- ;\r
- ; Switch to 16-bit operand size\r
- ;\r
- retf\r
-\r
-BITS 16\r
- ;\r
- ; At entry to this label\r
- ; - RDX will have its reset value\r
- ; - On the top of the stack\r
- ; - Alignment data (two bytes) to be discarded\r
- ; - IP for Real Mode (two bytes)\r
- ; - CS for Real Mode (two bytes)\r
- ;\r
- ; This label is also used with AsmRelocateApLoop. During MP finalization,\r
- ; the code from PM16Mode to SwitchToRealProcEnd is copied to the start of\r
- ; the WakeupBuffer, allowing a parked AP to be booted by an OS.\r
- ;\r
-PM16Mode:\r
- mov eax, cr0 ; Read CR0\r
- btr eax, 0 ; Set PE=0\r
- mov cr0, eax ; Write CR0\r
-\r
- pop ax ; Discard alignment data\r
-\r
- ;\r
- ; Clear registers (except RDX and RSP) before going into 16-bit mode\r
- ;\r
- xor eax, eax\r
- xor ebx, ebx\r
- xor ecx, ecx\r
- xor esi, esi\r
- xor edi, edi\r
- xor ebp, ebp\r
-\r
- iret\r
+;\r
+; Required for the AMD SEV helper functions\r
+;\r
+%include "AmdSev.nasm"\r
\r
-SwitchToRealProcEnd:\r
+RendezvousFunnelProcEnd:\r
\r
;-------------------------------------------------------------------------------------\r
; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);\r
;-------------------------------------------------------------------------------------\r
-global ASM_PFX(AsmRelocateApLoop)\r
-ASM_PFX(AsmRelocateApLoop):\r
AsmRelocateApLoopStart:\r
BITS 64\r
cmp qword [rsp + 56], 0 ; SevEsAPJumpTable\r
;-------------------------------------------------------------------------------------\r
global ASM_PFX(AsmGetAddressMap)\r
ASM_PFX(AsmGetAddressMap):\r
- lea rax, [ASM_PFX(RendezvousFunnelProc)]\r
+ lea rax, [RendezvousFunnelProcStart]\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelAddress], rax\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeEntryOffset], LongModeStart - RendezvousFunnelProcStart\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelSize], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
- lea rax, [ASM_PFX(AsmRelocateApLoop)]\r
+ lea rax, [AsmRelocateApLoopStart]\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddress], rax\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize], AsmRelocateApLoopEnd - AsmRelocateApLoopStart\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset], Flat32Start - RendezvousFunnelProcStart\r
- mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], SwitchToRealProcEnd - SwitchToRealProcStart\r
- mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], SwitchToRealProcStart - RendezvousFunnelProcStart\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset], SwitchToRealProcStart - Flat32Start\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOffset], PM16Mode - RendezvousFunnelProcStart\r
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSize], SwitchToRealProcEnd - PM16Mode\r