summaryrefslogtreecommitdiff
path: root/OvmfPkg/TdxDxe/X64/ApRunLoop.nasm
diff options
context:
space:
mode:
Diffstat (limited to 'OvmfPkg/TdxDxe/X64/ApRunLoop.nasm')
-rw-r--r--OvmfPkg/TdxDxe/X64/ApRunLoop.nasm138
1 files changed, 130 insertions, 8 deletions
diff --git a/OvmfPkg/TdxDxe/X64/ApRunLoop.nasm b/OvmfPkg/TdxDxe/X64/ApRunLoop.nasm
index 538ae71..62474fd 100644
--- a/OvmfPkg/TdxDxe/X64/ApRunLoop.nasm
+++ b/OvmfPkg/TdxDxe/X64/ApRunLoop.nasm
@@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ;
-; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2025, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
@@ -16,14 +16,34 @@
DEFAULT REL
+SECTION .bss
+global STACK_BASE
+STACK_BASE:
+ resb 1024
+STACK_TOP:
+
SECTION .text
+%define TDX_WORK_AREA_MAILBOX_GDTR (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 128)
+%define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
+%define TDX_WORK_AREA_PGTBL_READY (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 4)
+%define PG_5_LEVEL (FixedPcdGetBool (PcdUse5LevelPageTable))
+
+%define TDX_BSP 1
+%define TDX_AP 2
+%define TDX_AP_5_LEVEL 3
+
BITS 64
%define TDVMCALL_EXPOSE_REGS_MASK 0xffc4
%define TDVMCALL 0x0
%define EXIT_REASON_CPUID 0xa
+; Defined in ACPI 6.6 section 5.2.12.19 MultiProcessor Wakeup Mailbox Command.
+%define MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_NOOP 0
+%define MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_WAKEUP 1
+%define MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_TEST 2
+
%macro tdcall 0
db 0x66, 0x0f, 0x01, 0xcc
%endmacro
@@ -71,10 +91,11 @@ AsmRelocateApMailBoxLoopStart:
test r10, r10
jnz Panic
mov r8, r15
+ mov qword[rel mailbox_address], rbx
MailBoxLoop:
; Spin until command set
- cmp dword [rbx + CommandOffset], MpProtectedModeWakeupCommandNoop
+ cmp dword [rbx + CommandOffset], MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_NOOP
je MailBoxLoop
; Determine if this is a broadcast or directly for my apic-id, if not, ignore
cmp dword [rbx + ApicidOffset], MailboxApicidBroadcast
@@ -82,10 +103,10 @@ MailBoxLoop:
cmp dword [rbx + ApicidOffset], r8d
jne MailBoxLoop
MailBoxProcessCommand:
- cmp dword [rbx + CommandOffset], MpProtectedModeWakeupCommandWakeup
+ cmp dword [rbx + CommandOffset], MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_WAKEUP
je MailBoxWakeUp
- cmp dword [rbx + CommandOffset], MpProtectedModeWakeupCommandSleep
- je MailBoxSleep
+ cmp dword [rbx + CommandOffset], MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_TEST
+ je MailBoxTest
; Don't support this command, so ignore
jmp MailBoxLoop
MailBoxWakeUp:
@@ -94,10 +115,109 @@ MailBoxWakeUp:
; the command field back to zero as acknowledgement.
mov qword [rbx + CommandOffset], 0
jmp rax
-MailBoxSleep:
- jmp $
+MailBoxTest:
+ mov qword [rbx + CommandOffset], 0
+ jmp MailBoxLoop
Panic:
ud2
+
+AsmRelocateApResetVector:
+
+.prepareStack:
+ ; The stack can then be used to switch from long mode to compatibility mode
+ mov rsp, STACK_TOP
+
+.loadGDT:
+ cli
+ mov rax, TDX_WORK_AREA_MAILBOX_GDTR
+ lgdt [rax]
+
+.loadSwicthModeCode:
+ mov rcx, dword 0x10 ; load long mode selector
+ shl rcx, 32
+ lea rdx, [LongMode] ; assume address < 4G
+ or rcx, rdx
+ push rcx
+
+ mov rcx, dword 0x08 ; load compatible mode selector
+ shl rcx, 32
+ lea rdx, [Compatible] ; assume address < 4G
+ or rcx, rdx
+ push rcx
+ retf
+
+BITS 32
+Compatible:
+ mov eax, dword 0x18
+; ; reload DS/ES/SS to make sure they are correct referred to current GDT
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ ; reload the fs and gs
+ mov fs, ax
+ mov gs, ax
+
+ ; Must clear the CR4.PCIDE before clearing paging
+ mov ecx, cr4
+ btc ecx, 17
+ mov cr4, ecx
+ ;
+ ; Disable paging
+ ;
+ mov ecx, cr0
+ btc ecx, 31
+ mov cr0, ecx
+ ;
+RestoreCr0:
+ ; Only enable PE(bit 0), NE(bit 5), ET(bit 4) 0x31
+ mov eax, dword 0x31
+ mov cr0, eax
+
+
+ ; Only Enable MCE(bit 6), VMXE(bit 13) 0x2040
+ ; TDX enforeced the VMXE = 1 and mask it in VMM, so not set it.
+RestoreCr4:
+ mov eax, 0x40
+ mov cr4, eax
+
+%if PG_5_LEVEL
+ mov al, byte[TDX_WORK_AREA_PGTBL_READY]
+ inc eax
+ cmp eax, TDX_AP_5_LEVEL
+ jne SetCr3
+SetCr4La57:
+ ; set la57 bit in cr4
+ mov eax, cr4
+ bts eax, 12
+ mov cr4, eax
+%endif
+
+SetCr3:
+ ;
+ ; Can use the boot page tables since it's reserved
+
+ mov eax, PT_ADDR (0)
+ mov cr3, eax
+
+EnablePAE:
+ mov eax, cr4
+ bts eax, 5
+ mov cr4, eax
+
+EnablePaging:
+ mov eax, cr0
+ bts eax, 31 ; set PG
+ mov cr0, eax ; enable paging
+ ; return to LongMode
+ retf
+
+BITS 64
+LongMode:
+ mov rbx, qword[rel mailbox_address]
+ jmp AsmRelocateApMailBoxLoopStart
+align 16
+mailbox_address:
+ dq 0
BITS 64
AsmRelocateApMailBoxLoopEnd:
@@ -106,8 +226,10 @@ AsmRelocateApMailBoxLoopEnd:
;-------------------------------------------------------------------------------------
global ASM_PFX(AsmGetRelocationMap)
ASM_PFX(AsmGetRelocationMap):
+ ; mov byte[TDX_WORK_AREA_MB_PGTBL_READY], 0
lea rax, [AsmRelocateApMailBoxLoopStart]
mov qword [rcx], rax
mov qword [rcx + 8h], AsmRelocateApMailBoxLoopEnd - AsmRelocateApMailBoxLoopStart
+ lea rax, [AsmRelocateApResetVector]
+ mov qword [rcx + 10h], rax
ret
-