]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Sec/X64/SecEntry.nasm
OvmfPkg: Update Sec to support Tdx
[mirror_edk2.git] / OvmfPkg / Sec / X64 / SecEntry.nasm
index 1cc680a70716d45e6bf7222b36f954b49f397202..4528fec309a092ad42720c451cec58745deb8b88 100644 (file)
 ;------------------------------------------------------------------------------\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
@@ -35,6 +40,32 @@ extern ASM_PFX(SecCoreStartupWithStack)
 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
@@ -67,3 +98,54 @@ ASM_PFX(_ModuleEntryPoint):
     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