summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/Sec/X64/SecEntry.nasm
diff options
context:
space:
mode:
Diffstat (limited to 'OvmfPkg/Sec/X64/SecEntry.nasm')
-rw-r--r--OvmfPkg/Sec/X64/SecEntry.nasm82
1 files changed, 82 insertions, 0 deletions
diff --git a/OvmfPkg/Sec/X64/SecEntry.nasm b/OvmfPkg/Sec/X64/SecEntry.nasm
index 1cc680a707..4528fec309 100644
--- a/OvmfPkg/Sec/X64/SecEntry.nasm
+++ b/OvmfPkg/Sec/X64/SecEntry.nasm
@@ -10,12 +10,17 @@
;------------------------------------------------------------------------------
#include <Base.h>
+%include "TdxCommondefs.inc"
DEFAULT REL
SECTION .text
extern ASM_PFX(SecCoreStartupWithStack)
+%macro tdcall 0
+ db 0x66, 0x0f, 0x01, 0xcc
+%endmacro
+
;
; SecCore Entry Point
;
@@ -36,6 +41,32 @@ global ASM_PFX(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
;
+ ; Guest type is stored in OVMF_WORK_AREA
+ ;
+ %define OVMF_WORK_AREA FixedPcdGet32 (PcdOvmfWorkAreaBase)
+ %define VM_GUEST_TYPE_TDX 2
+ mov eax, OVMF_WORK_AREA
+ cmp byte[eax], VM_GUEST_TYPE_TDX
+ jne InitStack
+
+ mov rax, TDCALL_TDINFO
+ tdcall
+
+ ;
+ ; R8 [31:0] NUM_VCPUS
+ ; [63:32] MAX_VCPUS
+ ; R9 [31:0] VCPU_INDEX
+ ; Td Guest set the VCPU0 as the BSP, others are the APs
+ ; APs jump to spinloop and get released by DXE's MpInitLib
+ ;
+ mov rax, r9
+ and rax, 0xffff
+ test rax, rax
+ jne ParkAp
+
+InitStack:
+
+ ;
; Fill the temporary RAM with the initial stack value.
; The loop below will seed the heap as well, but that's harmless.
;
@@ -67,3 +98,54 @@ ASM_PFX(_ModuleEntryPoint):
sub rsp, 0x20
call ASM_PFX(SecCoreStartupWithStack)
+ ;
+ ; Note: BSP never gets here. APs will be unblocked by DXE
+ ;
+ ; R8 [31:0] NUM_VCPUS
+ ; [63:32] MAX_VCPUS
+ ; R9 [31:0] VCPU_INDEX
+ ;
+ParkAp:
+
+ mov rbp, r9
+
+.do_wait_loop:
+ mov rsp, FixedPcdGet32 (PcdOvmfSecGhcbBackupBase)
+
+ ;
+ ; register itself in [rsp + CpuArrivalOffset]
+ ;
+ mov rax, 1
+ lock xadd dword [rsp + CpuArrivalOffset], eax
+ inc eax
+
+.check_arrival_cnt:
+ cmp eax, r8d
+ je .check_command
+ mov eax, dword[rsp + CpuArrivalOffset]
+ jmp .check_arrival_cnt
+
+.check_command:
+ mov eax, dword[rsp + CommandOffset]
+ cmp eax, MpProtectedModeWakeupCommandNoop
+ je .check_command
+
+ cmp eax, MpProtectedModeWakeupCommandWakeup
+ je .do_wakeup
+
+ ; Don't support this command, so ignore
+ jmp .check_command
+
+.do_wakeup:
+ ;
+ ; BSP sets these variables before unblocking APs
+ ; RAX: WakeupVectorOffset
+ ; RBX: Relocated mailbox address
+ ; RBP: vCpuId
+ ;
+ mov rax, 0
+ mov eax, dword[rsp + WakeupVectorOffset]
+ mov rbx, [rsp + WakeupArgsRelocatedMailBox]
+ nop
+ jmp rax
+ jmp $