;------------------------------------------------------------------------------\r
\r
#include <Base.h>\r
+%include "TdxCommondefs.inc"\r
\r
DEFAULT REL\r
SECTION .text\r
\r
extern ASM_PFX(SecCoreStartupWithStack)\r
\r
+%macro tdcall 0\r
+ db 0x66, 0x0f, 0x01, 0xcc\r
+%endmacro\r
+\r
;\r
; SecCore Entry Point\r
;\r
global ASM_PFX(_ModuleEntryPoint)\r
ASM_PFX(_ModuleEntryPoint):\r
\r
+ ;\r
+ ; Guest type is stored in OVMF_WORK_AREA\r
+ ;\r
+ %define OVMF_WORK_AREA FixedPcdGet32 (PcdOvmfWorkAreaBase)\r
+ %define VM_GUEST_TYPE_TDX 2\r
+ mov eax, OVMF_WORK_AREA\r
+ cmp byte[eax], VM_GUEST_TYPE_TDX\r
+ jne InitStack\r
+\r
+ mov rax, TDCALL_TDINFO\r
+ tdcall\r
+\r
+ ;\r
+ ; R8 [31:0] NUM_VCPUS\r
+ ; [63:32] MAX_VCPUS\r
+ ; R9 [31:0] VCPU_INDEX\r
+ ; Td Guest set the VCPU0 as the BSP, others are the APs\r
+ ; APs jump to spinloop and get released by DXE's MpInitLib\r
+ ;\r
+ mov rax, r9\r
+ and rax, 0xffff\r
+ test rax, rax\r
+ jne ParkAp\r
+\r
+InitStack:\r
+\r
;\r
; Fill the temporary RAM with the initial stack value.\r
; The loop below will seed the heap as well, but that's harmless.\r
sub rsp, 0x20\r
call ASM_PFX(SecCoreStartupWithStack)\r
\r
+ ;\r
+ ; Note: BSP never gets here. APs will be unblocked by DXE\r
+ ;\r
+ ; R8 [31:0] NUM_VCPUS\r
+ ; [63:32] MAX_VCPUS\r
+ ; R9 [31:0] VCPU_INDEX\r
+ ;\r
+ParkAp:\r
+\r
+ mov rbp, r9\r
+\r
+.do_wait_loop:\r
+ mov rsp, FixedPcdGet32 (PcdOvmfSecGhcbBackupBase)\r
+\r
+ ;\r
+ ; register itself in [rsp + CpuArrivalOffset]\r
+ ;\r
+ mov rax, 1\r
+ lock xadd dword [rsp + CpuArrivalOffset], eax\r
+ inc eax\r
+\r
+.check_arrival_cnt:\r
+ cmp eax, r8d\r
+ je .check_command\r
+ mov eax, dword[rsp + CpuArrivalOffset]\r
+ jmp .check_arrival_cnt\r
+\r
+.check_command:\r
+ mov eax, dword[rsp + CommandOffset]\r
+ cmp eax, MpProtectedModeWakeupCommandNoop\r
+ je .check_command\r
+\r
+ cmp eax, MpProtectedModeWakeupCommandWakeup\r
+ je .do_wakeup\r
+\r
+ ; Don't support this command, so ignore\r
+ jmp .check_command\r
+\r
+.do_wakeup:\r
+ ;\r
+ ; BSP sets these variables before unblocking APs\r
+ ; RAX: WakeupVectorOffset\r
+ ; RBX: Relocated mailbox address\r
+ ; RBP: vCpuId\r
+ ;\r
+ mov rax, 0\r
+ mov eax, dword[rsp + WakeupVectorOffset]\r
+ mov rbx, [rsp + WakeupArgsRelocatedMailBox]\r
+ nop\r
+ jmp rax\r
+ jmp $\r