Files
system76-edk2/OvmfPkg/Library/TdxMailboxLib/TdxMailbox.c
Min M Xu a00b71b009 OvmfPkg/TdxMailboxLib: Delete global variables
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172

TdxMailboxLib once was designed to be used in DXE phase. But now it is
going to be used in SEC/PEI phase (in the following patches). Global
variables are not allowed. The library is refactored after those global
variables are deleted.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
2022-12-21 07:06:17 +00:00

140 lines
3.5 KiB
C

/** @file
Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiCpuLib.h>
#include <Library/SynchronizationLib.h>
#include <Uefi/UefiBaseType.h>
#include <IndustryStandard/IntelTdx.h>
#include <IndustryStandard/Tdx.h>
#include <Library/TdxMailboxLib.h>
/**
This function will be called by BSP to get the CPU number.
@retval CPU number
**/
UINT32
EFIAPI
GetCpusNum (
VOID
)
{
UINT64 Status;
TD_RETURN_DATA TdReturnData;
Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
if (Status == TDX_EXIT_REASON_SUCCESS) {
return TdReturnData.TdInfo.NumVcpus;
} else {
DEBUG ((DEBUG_ERROR, "Failed call TDCALL_TDINFO. %llx\n", Status));
}
return 0;
}
/**
Get the address of Td mailbox.
**/
volatile VOID *
EFIAPI
GetTdxMailBox (
VOID
)
{
return (VOID *)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase);
}
/**
This function will be called by BSP to wakeup APs the are spinning on mailbox
in protected mode
@param[in] Command Command to send APs
@param[in] WakeupVector If used, address for APs to start executing
@param[in] WakeArgsX Args to pass to APs for excuting commands
**/
VOID
EFIAPI
MpSendWakeupCommand (
IN UINT16 Command,
IN UINT64 WakeupVector,
IN UINT64 WakeupArgs1,
IN UINT64 WakeupArgs2,
IN UINT64 WakeupArgs3,
IN UINT64 WakeupArgs4
)
{
volatile MP_WAKEUP_MAILBOX *MailBox;
MailBox = (volatile MP_WAKEUP_MAILBOX *)GetTdxMailBox ();
MailBox->ApicId = MP_CPU_PROTECTED_MODE_MAILBOX_APICID_INVALID;
MailBox->WakeUpVector = 0;
MailBox->Command = MpProtectedModeWakeupCommandNoop;
MailBox->ApicId = MP_CPU_PROTECTED_MODE_MAILBOX_APICID_BROADCAST;
MailBox->WakeUpVector = WakeupVector;
MailBox->WakeUpArgs1 = WakeupArgs1;
MailBox->WakeUpArgs2 = WakeupArgs2;
MailBox->WakeUpArgs3 = WakeupArgs3;
MailBox->WakeUpArgs4 = WakeupArgs4;
AsmCpuid (0x01, NULL, NULL, NULL, NULL);
MailBox->Command = Command;
AsmCpuid (0x01, NULL, NULL, NULL, NULL);
return;
}
/**
BSP wait until all the APs arriving. It means the task triggered by BSP is started.
**/
VOID
EFIAPI
MpSerializeStart (
VOID
)
{
volatile MP_WAKEUP_MAILBOX *MailBox;
UINT32 NumOfCpus;
NumOfCpus = GetCpusNum ();
MailBox = (volatile MP_WAKEUP_MAILBOX *)GetTdxMailBox ();
DEBUG ((DEBUG_VERBOSE, "Waiting for APs to arriving. NumOfCpus=%d, MailBox=%p\n", NumOfCpus, MailBox));
while (MailBox->NumCpusArriving != (NumOfCpus -1)) {
CpuPause ();
}
DEBUG ((DEBUG_VERBOSE, "Releasing APs\n"));
MailBox->NumCpusExiting = NumOfCpus;
InterlockedIncrement ((UINT32 *)&MailBox->NumCpusArriving);
}
/**
BSP wait until all the APs arriving. It means the task triggered by BSP is ended.
**/
VOID
EFIAPI
MpSerializeEnd (
VOID
)
{
volatile MP_WAKEUP_MAILBOX *MailBox;
MailBox = (volatile MP_WAKEUP_MAILBOX *)GetTdxMailBox ();
DEBUG ((DEBUG_VERBOSE, "Waiting for APs to finish\n"));
while (MailBox->NumCpusExiting != 1 ) {
CpuPause ();
}
DEBUG ((DEBUG_VERBOSE, "Restarting APs\n"));
MailBox->Command = MpProtectedModeWakeupCommandNoop;
MailBox->NumCpusArriving = 0;
InterlockedDecrement ((UINT32 *)&MailBox->NumCpusExiting);
}