/** @file Copyright (c) 2008, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include /** 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); }