OvmfPkg/IntelTdx: Add Sec to bring up both Legacy and Tdx guest
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 OvmfPkg/IntelTdx/Sec is a simplied version of OvmfPkg/Sec. There are below differences between these 2 Sec - IntelTdx/Sec only supports Legacy guest and Tdx guest in X64. - IntelTdx/Sec calls PeilessStartup () to jump from SEC to DXE directly. - IntelTdx/Sec uses MemoryAllocationLib / HobLib / PrePiLib in EmbeddedPkg. Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
This commit is contained in:
151
OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm
Normal file
151
OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm
Normal file
@@ -0,0 +1,151 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
;* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;*
|
||||
;* CpuAsm.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
#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
|
||||
;
|
||||
; Processor is in flat protected mode
|
||||
;
|
||||
; @param[in] RAX Initial value of the EAX register (BIST: Built-in Self Test)
|
||||
; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor
|
||||
; @param[in] RBP Pointer to the start of the Boot Firmware Volume
|
||||
; @param[in] DS Selector allowing flat access to all addresses
|
||||
; @param[in] ES Selector allowing flat access to all addresses
|
||||
; @param[in] FS Selector allowing flat access to all addresses
|
||||
; @param[in] GS Selector allowing flat access to all addresses
|
||||
; @param[in] SS Selector allowing flat access to all addresses
|
||||
;
|
||||
; @return None This routine does not return
|
||||
;
|
||||
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.
|
||||
;
|
||||
mov rax, (FixedPcdGet32 (PcdInitValueInTempStack) << 32) | FixedPcdGet32 (PcdInitValueInTempStack)
|
||||
; qword to store
|
||||
mov rdi, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) ; base address,
|
||||
; relative to
|
||||
; ES
|
||||
mov rcx, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) / 8 ; qword count
|
||||
cld ; store from base
|
||||
; up
|
||||
rep stosq
|
||||
|
||||
;
|
||||
; Load temporary RAM stack based on PCDs
|
||||
;
|
||||
%define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + \
|
||||
FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
|
||||
mov rsp, SEC_TOP_OF_STACK
|
||||
nop
|
||||
|
||||
;
|
||||
; Setup parameters and call SecCoreStartupWithStack
|
||||
; rcx: BootFirmwareVolumePtr
|
||||
; rdx: TopOfCurrentStack
|
||||
;
|
||||
mov rcx, rbp
|
||||
mov rdx, rsp
|
||||
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 $
|
Reference in New Issue
Block a user