mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-06 21:34:23 +02:00
UefiCpuPkg: Add multiprocessor library for LoongArch64
Added LoongArch multiprocessor initialization instance into MpInitLib. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4734 Cc: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Chao Li <lichao@loongson.cn> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
parent
392a368533
commit
abaf405ed9
@ -2,6 +2,7 @@
|
|||||||
# MP Initialize Library instance for DXE driver.
|
# MP Initialize Library instance for DXE driver.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@ -18,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
# The following information is for reference only and not required by the build tools.
|
# The following information is for reference only and not required by the build tools.
|
||||||
#
|
#
|
||||||
# VALID_ARCHITECTURES = IA32 X64
|
# VALID_ARCHITECTURES = IA32 X64 LOONGARCH64
|
||||||
#
|
#
|
||||||
|
|
||||||
[Sources.IA32]
|
[Sources.IA32]
|
||||||
@ -31,7 +32,7 @@
|
|||||||
X64/CreatePageTable.c
|
X64/CreatePageTable.c
|
||||||
X64/MpFuncs.nasm
|
X64/MpFuncs.nasm
|
||||||
|
|
||||||
[Sources.common]
|
[Sources.IA32, Sources.X64]
|
||||||
AmdSev.c
|
AmdSev.c
|
||||||
DxeMpLib.c
|
DxeMpLib.c
|
||||||
Microcode.c
|
Microcode.c
|
||||||
@ -40,6 +41,11 @@
|
|||||||
MpLib.h
|
MpLib.h
|
||||||
MpHandOff.h
|
MpHandOff.h
|
||||||
|
|
||||||
|
[Sources.LoongArch64]
|
||||||
|
LoongArch64/DxeMpLib.c
|
||||||
|
LoongArch64/MpLib.c
|
||||||
|
LoongArch64/MpLib.h
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
MdeModulePkg/MdeModulePkg.dec
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
@ -47,18 +53,20 @@
|
|||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
CcExitLib
|
|
||||||
CpuLib
|
CpuLib
|
||||||
DebugAgentLib
|
DebugAgentLib
|
||||||
HobLib
|
HobLib
|
||||||
LocalApicLib
|
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
MicrocodeLib
|
|
||||||
MtrrLib
|
|
||||||
PcdLib
|
PcdLib
|
||||||
SynchronizationLib
|
SynchronizationLib
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
|
||||||
|
[LibraryClasses.IA32, LibraryClasses.X64]
|
||||||
|
CcExitLib
|
||||||
|
LocalApicLib
|
||||||
|
MicrocodeLib
|
||||||
|
MtrrLib
|
||||||
|
|
||||||
[LibraryClasses.X64]
|
[LibraryClasses.X64]
|
||||||
CpuPageTableLib
|
CpuPageTableLib
|
||||||
|
|
||||||
@ -70,6 +78,9 @@
|
|||||||
gEfiEventLegacyBootGuid ## SOMETIMES_CONSUMES ## Event
|
gEfiEventLegacyBootGuid ## SOMETIMES_CONSUMES ## Event
|
||||||
gEdkiiMicrocodePatchHobGuid ## SOMETIMES_CONSUMES ## HOB
|
gEdkiiMicrocodePatchHobGuid ## SOMETIMES_CONSUMES ## HOB
|
||||||
|
|
||||||
|
[Guids.LoongArch64]
|
||||||
|
gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
|
||||||
|
480
UefiCpuPkg/Library/MpInitLib/LoongArch64/DxeMpLib.c
Normal file
480
UefiCpuPkg/Library/MpInitLib/LoongArch64/DxeMpLib.c
Normal file
@ -0,0 +1,480 @@
|
|||||||
|
/** @file
|
||||||
|
LoongArch64 MP initialize support functions for DXE phase.
|
||||||
|
|
||||||
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "MpLib.h"
|
||||||
|
|
||||||
|
#include <Library/DebugAgentLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
|
||||||
|
#include <Protocol/Timer.h>
|
||||||
|
|
||||||
|
CPU_MP_DATA *mCpuMpData = NULL;
|
||||||
|
EFI_EVENT mCheckAllApsEvent = NULL;
|
||||||
|
volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable Debug Agent to support source debugging on AP function.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EnableDebugAgent (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Initialize Debug Agent to support source level debug in DXE phase
|
||||||
|
//
|
||||||
|
InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_AP, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the pointer to CPU MP Data structure.
|
||||||
|
|
||||||
|
@return The pointer to CPU MP Data structure.
|
||||||
|
**/
|
||||||
|
CPU_MP_DATA *
|
||||||
|
GetCpuMpData (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (mCpuMpData != NULL);
|
||||||
|
return mCpuMpData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save the pointer to CPU MP Data structure.
|
||||||
|
|
||||||
|
@param[in] CpuMpData The pointer to CPU MP Data structure will be saved.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SaveCpuMpData (
|
||||||
|
IN CPU_MP_DATA *CpuMpData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
mCpuMpData = CpuMpData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get available EfiBootServicesCode memory below 4GB by specified size.
|
||||||
|
|
||||||
|
This buffer is required to safely transfer AP from real address mode to
|
||||||
|
protected mode or long mode, due to the fact that the buffer returned by
|
||||||
|
GetWakeupBuffer() may be marked as non-executable.
|
||||||
|
|
||||||
|
@param[in] BufferSize Wakeup transition buffer size.
|
||||||
|
|
||||||
|
@retval other Return wakeup transition buffer address below 4GB.
|
||||||
|
@retval 0 Cannot find free memory below 4GB.
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
GetModeTransitionBuffer (
|
||||||
|
IN UINTN BufferSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks APs status and updates APs status if needed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
CheckAndUpdateApsStatus (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN ProcessorNumber;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
CPU_MP_DATA *CpuMpData;
|
||||||
|
|
||||||
|
CpuMpData = GetCpuMpData ();
|
||||||
|
|
||||||
|
//
|
||||||
|
// First, check whether pending StartupAllAPs() exists.
|
||||||
|
//
|
||||||
|
if (CpuMpData->WaitEvent != NULL) {
|
||||||
|
Status = CheckAllAPs ();
|
||||||
|
//
|
||||||
|
// If all APs finish for StartupAllAPs(), signal the WaitEvent for it.
|
||||||
|
//
|
||||||
|
if (Status != EFI_NOT_READY) {
|
||||||
|
Status = gBS->SignalEvent (CpuMpData->WaitEvent);
|
||||||
|
CpuMpData->WaitEvent = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Second, check whether pending StartupThisAPs() callings exist.
|
||||||
|
//
|
||||||
|
for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) {
|
||||||
|
if (CpuMpData->CpuData[ProcessorNumber].WaitEvent == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = CheckThisAP (ProcessorNumber);
|
||||||
|
|
||||||
|
if (Status != EFI_NOT_READY) {
|
||||||
|
gBS->SignalEvent (CpuMpData->CpuData[ProcessorNumber].WaitEvent);
|
||||||
|
CpuMpData->CpuData[ProcessorNumber].WaitEvent = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks APs' status periodically.
|
||||||
|
|
||||||
|
This function is triggered by timer periodically to check the
|
||||||
|
state of APs for StartupAllAPs() and StartupThisAP() executed
|
||||||
|
in non-blocking mode.
|
||||||
|
|
||||||
|
@param[in] Event Event triggered.
|
||||||
|
@param[in] Context Parameter passed with the event.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
CheckApsStatus (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// If CheckApsStatus() is not stopped, otherwise return immediately.
|
||||||
|
//
|
||||||
|
if (!mStopCheckAllApsStatus) {
|
||||||
|
CheckAndUpdateApsStatus ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize global data for MP support.
|
||||||
|
|
||||||
|
@param[in] CpuMpData The pointer to CPU MP Data structure.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
InitMpGlobalData (
|
||||||
|
IN CPU_MP_DATA *CpuMpData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
SaveCpuMpData (CpuMpData);
|
||||||
|
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
CheckApsStatus,
|
||||||
|
NULL,
|
||||||
|
&mCheckAllApsEvent
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set timer to check all APs status.
|
||||||
|
//
|
||||||
|
Status = gBS->SetTimer (
|
||||||
|
mCheckAllApsEvent,
|
||||||
|
TimerPeriodic,
|
||||||
|
EFI_TIMER_PERIOD_MICROSECONDS (
|
||||||
|
PcdGet32 (PcdCpuApStatusCheckIntervalInMicroSeconds)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This service executes a caller provided function on all enabled APs.
|
||||||
|
|
||||||
|
@param[in] Procedure A pointer to the function to be run on
|
||||||
|
enabled APs of the system. See type
|
||||||
|
EFI_AP_PROCEDURE.
|
||||||
|
@param[in] SingleThread If TRUE, then all the enabled APs execute
|
||||||
|
the function specified by Procedure one by
|
||||||
|
one, in ascending order of processor handle
|
||||||
|
number. If FALSE, then all the enabled APs
|
||||||
|
execute the function specified by Procedure
|
||||||
|
simultaneously.
|
||||||
|
@param[in] WaitEvent The event created by the caller with CreateEvent()
|
||||||
|
service. If it is NULL, then execute in
|
||||||
|
blocking mode. BSP waits until all APs finish
|
||||||
|
or TimeoutInMicroSeconds expires. If it's
|
||||||
|
not NULL, then execute in non-blocking mode.
|
||||||
|
BSP requests the function specified by
|
||||||
|
Procedure to be started on all the enabled
|
||||||
|
APs, and go on executing immediately. If
|
||||||
|
all return from Procedure, or TimeoutInMicroSeconds
|
||||||
|
expires, this event is signaled. The BSP
|
||||||
|
can use the CheckEvent() or WaitForEvent()
|
||||||
|
services to check the state of event. Type
|
||||||
|
EFI_EVENT is defined in CreateEvent() in
|
||||||
|
the Unified Extensible Firmware Interface
|
||||||
|
Specification.
|
||||||
|
@param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
|
||||||
|
APs to return from Procedure, either for
|
||||||
|
blocking or non-blocking mode. Zero means
|
||||||
|
infinity. If the timeout expires before
|
||||||
|
all APs return from Procedure, then Procedure
|
||||||
|
on the failed APs is terminated. All enabled
|
||||||
|
APs are available for next function assigned
|
||||||
|
by MpInitLibStartupAllAPs() or
|
||||||
|
MPInitLibStartupThisAP().
|
||||||
|
If the timeout expires in blocking mode,
|
||||||
|
BSP returns EFI_TIMEOUT. If the timeout
|
||||||
|
expires in non-blocking mode, WaitEvent
|
||||||
|
is signaled with SignalEvent().
|
||||||
|
@param[in] ProcedureArgument The parameter passed into Procedure for
|
||||||
|
all APs.
|
||||||
|
@param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
|
||||||
|
if all APs finish successfully, then its
|
||||||
|
content is set to NULL. If not all APs
|
||||||
|
finish before timeout expires, then its
|
||||||
|
content is set to address of the buffer
|
||||||
|
holding handle numbers of the failed APs.
|
||||||
|
The buffer is allocated by MP Initialization
|
||||||
|
library, and it's the caller's responsibility to
|
||||||
|
free the buffer with FreePool() service.
|
||||||
|
In blocking mode, it is ready for consumption
|
||||||
|
when the call returns. In non-blocking mode,
|
||||||
|
it is ready when WaitEvent is signaled. The
|
||||||
|
list of failed CPU is terminated by
|
||||||
|
END_OF_CPU_LIST.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS In blocking mode, all APs have finished before
|
||||||
|
the timeout expired.
|
||||||
|
@retval EFI_SUCCESS In non-blocking mode, function has been dispatched
|
||||||
|
to all enabled APs.
|
||||||
|
@retval EFI_UNSUPPORTED A non-blocking mode request was made after the
|
||||||
|
UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
|
||||||
|
signaled.
|
||||||
|
@retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not
|
||||||
|
supported.
|
||||||
|
@retval EFI_DEVICE_ERROR Caller processor is AP.
|
||||||
|
@retval EFI_NOT_STARTED No enabled APs exist in the system.
|
||||||
|
@retval EFI_NOT_READY Any enabled APs are busy.
|
||||||
|
@retval EFI_NOT_READY MP Initialize Library is not initialized.
|
||||||
|
@retval EFI_TIMEOUT In blocking mode, the timeout expired before
|
||||||
|
all enabled APs have finished.
|
||||||
|
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MpInitLibStartupAllAPs (
|
||||||
|
IN EFI_AP_PROCEDURE Procedure,
|
||||||
|
IN BOOLEAN SingleThread,
|
||||||
|
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||||
|
IN UINTN TimeoutInMicroseconds,
|
||||||
|
IN VOID *ProcedureArgument OPTIONAL,
|
||||||
|
OUT UINTN **FailedCpuList OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Temporarily stop checkAllApsStatus for avoid resource dead-lock.
|
||||||
|
//
|
||||||
|
mStopCheckAllApsStatus = TRUE;
|
||||||
|
|
||||||
|
Status = StartupAllCPUsWorker (
|
||||||
|
Procedure,
|
||||||
|
SingleThread,
|
||||||
|
TRUE,
|
||||||
|
WaitEvent,
|
||||||
|
TimeoutInMicroseconds,
|
||||||
|
ProcedureArgument,
|
||||||
|
FailedCpuList
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start checkAllApsStatus
|
||||||
|
//
|
||||||
|
mStopCheckAllApsStatus = FALSE;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This service lets the caller get one enabled AP to execute a caller-provided
|
||||||
|
function.
|
||||||
|
|
||||||
|
@param[in] Procedure A pointer to the function to be run on the
|
||||||
|
designated AP of the system. See type
|
||||||
|
EFI_AP_PROCEDURE.
|
||||||
|
@param[in] ProcessorNumber The handle number of the AP. The range is
|
||||||
|
from 0 to the total number of logical
|
||||||
|
processors minus 1. The total number of
|
||||||
|
logical processors can be retrieved by
|
||||||
|
MpInitLibGetNumberOfProcessors().
|
||||||
|
@param[in] WaitEvent The event created by the caller with CreateEvent()
|
||||||
|
service. If it is NULL, then execute in
|
||||||
|
blocking mode. BSP waits until this AP finish
|
||||||
|
or TimeoutInMicroSeconds expires. If it's
|
||||||
|
not NULL, then execute in non-blocking mode.
|
||||||
|
BSP requests the function specified by
|
||||||
|
Procedure to be started on this AP,
|
||||||
|
and go on executing immediately. If this AP
|
||||||
|
return from Procedure or TimeoutInMicroSeconds
|
||||||
|
expires, this event is signaled. The BSP
|
||||||
|
can use the CheckEvent() or WaitForEvent()
|
||||||
|
services to check the state of event. Type
|
||||||
|
EFI_EVENT is defined in CreateEvent() in
|
||||||
|
the Unified Extensible Firmware Interface
|
||||||
|
Specification.
|
||||||
|
@param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
|
||||||
|
this AP to finish this Procedure, either for
|
||||||
|
blocking or non-blocking mode. Zero means
|
||||||
|
infinity. If the timeout expires before
|
||||||
|
this AP returns from Procedure, then Procedure
|
||||||
|
on the AP is terminated. The
|
||||||
|
AP is available for next function assigned
|
||||||
|
by MpInitLibStartupAllAPs() or
|
||||||
|
MpInitLibStartupThisAP().
|
||||||
|
If the timeout expires in blocking mode,
|
||||||
|
BSP returns EFI_TIMEOUT. If the timeout
|
||||||
|
expires in non-blocking mode, WaitEvent
|
||||||
|
is signaled with SignalEvent().
|
||||||
|
@param[in] ProcedureArgument The parameter passed into Procedure on the
|
||||||
|
specified AP.
|
||||||
|
@param[out] Finished If NULL, this parameter is ignored. In
|
||||||
|
blocking mode, this parameter is ignored.
|
||||||
|
In non-blocking mode, if AP returns from
|
||||||
|
Procedure before the timeout expires, its
|
||||||
|
content is set to TRUE. Otherwise, the
|
||||||
|
value is set to FALSE. The caller can
|
||||||
|
determine if the AP returned from Procedure
|
||||||
|
by evaluating this value.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS In blocking mode, specified AP finished before
|
||||||
|
the timeout expires.
|
||||||
|
@retval EFI_SUCCESS In non-blocking mode, the function has been
|
||||||
|
dispatched to specified AP.
|
||||||
|
@retval EFI_UNSUPPORTED A non-blocking mode request was made after the
|
||||||
|
UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
|
||||||
|
signaled.
|
||||||
|
@retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not
|
||||||
|
supported.
|
||||||
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
|
@retval EFI_TIMEOUT In blocking mode, the timeout expired before
|
||||||
|
the specified AP has finished.
|
||||||
|
@retval EFI_NOT_READY The specified AP is busy.
|
||||||
|
@retval EFI_NOT_READY MP Initialize Library is not initialized.
|
||||||
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
|
ProcessorNumber does not exist.
|
||||||
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
|
||||||
|
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MpInitLibStartupThisAP (
|
||||||
|
IN EFI_AP_PROCEDURE Procedure,
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||||
|
IN UINTN TimeoutInMicroseconds,
|
||||||
|
IN VOID *ProcedureArgument OPTIONAL,
|
||||||
|
OUT BOOLEAN *Finished OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// temporarily stop checkAllApsStatus for avoid resource dead-lock.
|
||||||
|
//
|
||||||
|
mStopCheckAllApsStatus = TRUE;
|
||||||
|
|
||||||
|
Status = StartupThisAPWorker (
|
||||||
|
Procedure,
|
||||||
|
ProcessorNumber,
|
||||||
|
WaitEvent,
|
||||||
|
TimeoutInMicroseconds,
|
||||||
|
ProcedureArgument,
|
||||||
|
Finished
|
||||||
|
);
|
||||||
|
|
||||||
|
mStopCheckAllApsStatus = FALSE;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This service switches the requested AP to be the BSP from that point onward.
|
||||||
|
This service changes the BSP for all purposes. This call can only be performed
|
||||||
|
by the current BSP.
|
||||||
|
|
||||||
|
@param[in] ProcessorNumber The handle number of AP that is to become the new
|
||||||
|
BSP. The range is from 0 to the total number of
|
||||||
|
logical processors minus 1. The total number of
|
||||||
|
logical processors can be retrieved by
|
||||||
|
MpInitLibGetNumberOfProcessors().
|
||||||
|
@param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
|
||||||
|
enabled AP. Otherwise, it will be disabled.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS BSP successfully switched.
|
||||||
|
@retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
|
||||||
|
this service returning.
|
||||||
|
@retval EFI_UNSUPPORTED Switching the BSP is not supported.
|
||||||
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
|
ProcessorNumber does not exist.
|
||||||
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
|
||||||
|
a disabled AP.
|
||||||
|
@retval EFI_NOT_READY The specified AP is busy.
|
||||||
|
@retval EFI_NOT_READY MP Initialize Library is not initialized.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MpInitLibSwitchBSP (
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN BOOLEAN EnableOldBSP
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This service lets the caller enable or disable an AP from this point onward.
|
||||||
|
This service may only be called from the BSP.
|
||||||
|
|
||||||
|
@param[in] ProcessorNumber The handle number of AP.
|
||||||
|
The range is from 0 to the total number of
|
||||||
|
logical processors minus 1. The total number of
|
||||||
|
logical processors can be retrieved by
|
||||||
|
MpInitLibGetNumberOfProcessors().
|
||||||
|
@param[in] EnableAP Specifies the new state for the processor for
|
||||||
|
enabled, FALSE for disabled.
|
||||||
|
@param[in] HealthFlag If not NULL, a pointer to a value that specifies
|
||||||
|
the new health status of the AP. This flag
|
||||||
|
corresponds to StatusFlag defined in
|
||||||
|
EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
|
||||||
|
the PROCESSOR_HEALTH_STATUS_BIT is used. All other
|
||||||
|
bits are ignored. If it is NULL, this parameter
|
||||||
|
is ignored.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
|
||||||
|
@retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
|
||||||
|
prior to this service returning.
|
||||||
|
@retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
|
||||||
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
|
@retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
|
||||||
|
does not exist.
|
||||||
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
|
||||||
|
@retval EFI_NOT_READY MP Initialize Library is not initialized.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MpInitLibEnableDisableAP (
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN BOOLEAN EnableAP,
|
||||||
|
IN UINT32 *HealthFlag OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
1626
UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c
Normal file
1626
UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c
Normal file
File diff suppressed because it is too large
Load Diff
350
UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.h
Normal file
350
UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.h
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
/** @file
|
||||||
|
Common header file for LoongArch MP Initialize Library.
|
||||||
|
|
||||||
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef MP_LIB_H_
|
||||||
|
#define MP_LIB_H_
|
||||||
|
|
||||||
|
#include <PiPei.h>
|
||||||
|
#include <Guid/ProcessorResourceHob.h>
|
||||||
|
#include <Library/PeiServicesLib.h>
|
||||||
|
|
||||||
|
#include <Library/MpInitLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/CpuLib.h>
|
||||||
|
#include <Library/SynchronizationLib.h>
|
||||||
|
#include <Library/TimerLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
|
|
||||||
|
#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
|
||||||
|
|
||||||
|
#define CPU_INIT_MP_LIB_HOB_GUID \
|
||||||
|
{ \
|
||||||
|
0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// AP loop state when APs are in idle state
|
||||||
|
// It's value is the same with PcdCpuApLoopMode
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
ApInHltLoop = 1,
|
||||||
|
ApInRunLoop = 2
|
||||||
|
} AP_LOOP_MODE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// AP initialization state during APs wakeup
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
ApInitConfig = 1,
|
||||||
|
ApInitReconfig = 2,
|
||||||
|
ApInitDone = 3
|
||||||
|
} AP_INIT_STATE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// AP state
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
CpuStateIdle,
|
||||||
|
CpuStateReady,
|
||||||
|
CpuStateBusy,
|
||||||
|
CpuStateFinished,
|
||||||
|
CpuStateDisabled
|
||||||
|
} CPU_STATE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// AP related data
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
SPIN_LOCK ApLock;
|
||||||
|
volatile UINT32 *StartupApSignal;
|
||||||
|
volatile UINTN ApFunction;
|
||||||
|
volatile UINTN ApFunctionArgument;
|
||||||
|
BOOLEAN CpuHealthy;
|
||||||
|
volatile CPU_STATE State;
|
||||||
|
BOOLEAN Waiting;
|
||||||
|
BOOLEAN *Finished;
|
||||||
|
UINT64 ExpectedTime;
|
||||||
|
UINT64 CurrentTime;
|
||||||
|
UINT64 TotalTime;
|
||||||
|
EFI_EVENT WaitEvent;
|
||||||
|
} CPU_AP_DATA;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Basic CPU information saved in Guided HOB.
|
||||||
|
// Because the contents will be shard between PEI and DXE,
|
||||||
|
// we need to make sure the each fields offset same in different
|
||||||
|
// architecture.
|
||||||
|
//
|
||||||
|
#pragma pack (1)
|
||||||
|
typedef struct {
|
||||||
|
UINT32 ApicId;
|
||||||
|
UINT32 Health;
|
||||||
|
} CPU_INFO_IN_HOB;
|
||||||
|
#pragma pack ()
|
||||||
|
|
||||||
|
typedef struct MP_CPU_DATA CPU_MP_DATA;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MP CPU exchange information for AP reset code
|
||||||
|
// This structure is required to be packed because fixed field offsets
|
||||||
|
// into this structure are used in assembly code in this module
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
CPU_MP_DATA *CpuMpData;
|
||||||
|
} MP_CPU_EXCHANGE_INFO;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
//
|
||||||
|
// CPU MP Data save in memory
|
||||||
|
//
|
||||||
|
struct MP_CPU_DATA {
|
||||||
|
UINT64 CpuInfoInHob;
|
||||||
|
UINT32 CpuCount;
|
||||||
|
UINT32 BspNumber;
|
||||||
|
//
|
||||||
|
// The above fields data will be passed from PEI to DXE
|
||||||
|
// Please make sure the fields offset same in the different
|
||||||
|
// architecture.
|
||||||
|
//
|
||||||
|
SPIN_LOCK MpLock;
|
||||||
|
|
||||||
|
volatile UINT32 FinishedCount;
|
||||||
|
UINT32 RunningCount;
|
||||||
|
BOOLEAN SingleThread;
|
||||||
|
EFI_AP_PROCEDURE Procedure;
|
||||||
|
VOID *ProcArguments;
|
||||||
|
BOOLEAN *Finished;
|
||||||
|
UINT64 ExpectedTime;
|
||||||
|
UINT64 CurrentTime;
|
||||||
|
UINT64 TotalTime;
|
||||||
|
EFI_EVENT WaitEvent;
|
||||||
|
|
||||||
|
AP_INIT_STATE InitFlag;
|
||||||
|
UINT8 ApLoopMode;
|
||||||
|
CPU_AP_DATA *CpuData;
|
||||||
|
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern EFI_GUID mCpuInitMpLibHobGuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the pointer to CPU MP Data structure.
|
||||||
|
|
||||||
|
@return The pointer to CPU MP Data structure.
|
||||||
|
**/
|
||||||
|
CPU_MP_DATA *
|
||||||
|
GetCpuMpData (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save the pointer to CPU MP Data structure.
|
||||||
|
|
||||||
|
@param[in] CpuMpData The pointer to CPU MP Data structure will be saved.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SaveCpuMpData (
|
||||||
|
IN CPU_MP_DATA *CpuMpData
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function will be called by BSP to wakeup AP.
|
||||||
|
|
||||||
|
@param[in] CpuMpData Pointer to CPU MP Data
|
||||||
|
@param[in] Broadcast TRUE: Send broadcast IPI to all APs
|
||||||
|
FALSE: Send IPI to AP by ApicId
|
||||||
|
@param[in] ProcessorNumber The handle number of specified processor
|
||||||
|
@param[in] Procedure The function to be invoked by AP
|
||||||
|
@param[in] ProcedureArgument The argument to be passed into AP function
|
||||||
|
@param[in] WakeUpDisabledAps Whether need to wake up disabled APs in broadcast mode.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
WakeUpAP (
|
||||||
|
IN CPU_MP_DATA *CpuMpData,
|
||||||
|
IN BOOLEAN Broadcast,
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN EFI_AP_PROCEDURE Procedure OPTIONAL,
|
||||||
|
IN VOID *ProcedureArgument OPTIONAL,
|
||||||
|
IN BOOLEAN WakeUpDisabledAps
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize global data for MP support.
|
||||||
|
|
||||||
|
@param[in] CpuMpData The pointer to CPU MP Data structure.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
InitMpGlobalData (
|
||||||
|
IN CPU_MP_DATA *CpuMpData
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Worker function to execute a caller provided function on all enabled APs.
|
||||||
|
|
||||||
|
@param[in] Procedure A pointer to the function to be run on
|
||||||
|
enabled APs of the system.
|
||||||
|
@param[in] SingleThread If TRUE, then all the enabled APs execute
|
||||||
|
the function specified by Procedure one by
|
||||||
|
one, in ascending order of processor handle
|
||||||
|
number. If FALSE, then all the enabled APs
|
||||||
|
execute the function specified by Procedure
|
||||||
|
simultaneously.
|
||||||
|
@param[in] WaitEvent The event created by the caller with CreateEvent()
|
||||||
|
service.
|
||||||
|
@param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
|
||||||
|
APs to return from Procedure, either for
|
||||||
|
blocking or non-blocking mode.
|
||||||
|
@param[in] ProcedureArgument The parameter passed into Procedure for
|
||||||
|
all APs.
|
||||||
|
@param[out] FailedCpuList If all APs finish successfully, then its
|
||||||
|
content is set to NULL. If not all APs
|
||||||
|
finish before timeout expires, then its
|
||||||
|
content is set to address of the buffer
|
||||||
|
holding handle numbers of the failed APs.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS In blocking mode, all APs have finished before
|
||||||
|
the timeout expired.
|
||||||
|
@retval EFI_SUCCESS In non-blocking mode, function has been dispatched
|
||||||
|
to all enabled APs.
|
||||||
|
@retval others Failed to Startup all APs.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
StartupAllCPUsWorker (
|
||||||
|
IN EFI_AP_PROCEDURE Procedure,
|
||||||
|
IN BOOLEAN SingleThread,
|
||||||
|
IN BOOLEAN ExcludeBsp,
|
||||||
|
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||||
|
IN UINTN TimeoutInMicroseconds,
|
||||||
|
IN VOID *ProcedureArgument OPTIONAL,
|
||||||
|
OUT UINTN **FailedCpuList OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Worker function to let the caller get one enabled AP to execute a caller-provided
|
||||||
|
function.
|
||||||
|
|
||||||
|
@param[in] Procedure A pointer to the function to be run on
|
||||||
|
enabled APs of the system.
|
||||||
|
@param[in] ProcessorNumber The handle number of the AP.
|
||||||
|
@param[in] WaitEvent The event created by the caller with CreateEvent()
|
||||||
|
service.
|
||||||
|
@param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
|
||||||
|
APs to return from Procedure, either for
|
||||||
|
blocking or non-blocking mode.
|
||||||
|
@param[in] ProcedureArgument The parameter passed into Procedure for
|
||||||
|
all APs.
|
||||||
|
@param[out] Finished If AP returns from Procedure before the
|
||||||
|
timeout expires, its content is set to TRUE.
|
||||||
|
Otherwise, the value is set to FALSE.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS In blocking mode, specified AP finished before
|
||||||
|
the timeout expires.
|
||||||
|
@retval others Failed to Startup AP.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
StartupThisAPWorker (
|
||||||
|
IN EFI_AP_PROCEDURE Procedure,
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||||
|
IN UINTN TimeoutInMicroseconds,
|
||||||
|
IN VOID *ProcedureArgument OPTIONAL,
|
||||||
|
OUT BOOLEAN *Finished OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Worker function to let the caller enable or disable an AP from this point onward.
|
||||||
|
This service may only be called from the BSP.
|
||||||
|
This instance will be added in the future.
|
||||||
|
|
||||||
|
@param[in] ProcessorNumber The handle number of AP.
|
||||||
|
@param[in] EnableAP Specifies the new state for the processor for
|
||||||
|
enabled, FALSE for disabled.
|
||||||
|
@param[in] HealthFlag If not NULL, a pointer to a value that specifies
|
||||||
|
the new health status of the AP.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
|
||||||
|
@retval others Failed to Enable/Disable AP.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EnableDisableApWorker (
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN BOOLEAN EnableAP,
|
||||||
|
IN UINT32 *HealthFlag OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get pointer to CPU MP Data structure from GUIDed HOB.
|
||||||
|
|
||||||
|
@return The pointer to CPU MP Data structure.
|
||||||
|
**/
|
||||||
|
CPU_MP_DATA *
|
||||||
|
GetCpuMpDataFromGuidedHob (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Checks status of specified AP.
|
||||||
|
|
||||||
|
This function checks whether the specified AP has finished the task assigned
|
||||||
|
by StartupThisAP(), and whether timeout expires.
|
||||||
|
|
||||||
|
@param[in] ProcessorNumber The handle number of processor.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().
|
||||||
|
@retval EFI_TIMEOUT The timeout expires.
|
||||||
|
@retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
CheckThisAP (
|
||||||
|
IN UINTN ProcessorNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks status of all APs.
|
||||||
|
|
||||||
|
This function checks whether all APs have finished task assigned by StartupAllAPs(),
|
||||||
|
and whether timeout expires.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs().
|
||||||
|
@retval EFI_TIMEOUT The timeout expires.
|
||||||
|
@retval EFI_NOT_READY APs have not finished task and timeout has not expired.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
CheckAllAPs (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks APs status and updates APs status if needed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
CheckAndUpdateApsStatus (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable Debug Agent to support source debugging on AP function.
|
||||||
|
This instance will added in the future.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EnableDebugAgent (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
381
UefiCpuPkg/Library/MpInitLib/LoongArch64/PeiMpLib.c
Normal file
381
UefiCpuPkg/Library/MpInitLib/LoongArch64/PeiMpLib.c
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
/** @file
|
||||||
|
LoongArch64 MP initialize support functions for PEI phase.
|
||||||
|
|
||||||
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "MpLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable Debug Agent to support source debugging on AP function.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EnableDebugAgent (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get pointer to CPU MP Data structure.
|
||||||
|
|
||||||
|
@return The pointer to CPU MP Data structure.
|
||||||
|
**/
|
||||||
|
CPU_MP_DATA *
|
||||||
|
GetCpuMpData (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CPU_MP_DATA *CpuMpData;
|
||||||
|
|
||||||
|
CpuMpData = GetCpuMpDataFromGuidedHob ();
|
||||||
|
ASSERT (CpuMpData != NULL);
|
||||||
|
return CpuMpData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save the pointer to CPU MP Data structure.
|
||||||
|
|
||||||
|
@param[in] CpuMpData The pointer to CPU MP Data structure will be saved.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SaveCpuMpData (
|
||||||
|
IN CPU_MP_DATA *CpuMpData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 Data64;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build location of CPU MP DATA buffer in HOB
|
||||||
|
//
|
||||||
|
Data64 = (UINT64)(UINTN)CpuMpData;
|
||||||
|
BuildGuidDataHob (
|
||||||
|
&mCpuInitMpLibHobGuid,
|
||||||
|
(VOID *)&Data64,
|
||||||
|
sizeof (UINT64)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get available EfiBootServicesCode memory below 4GB by specified size.
|
||||||
|
|
||||||
|
This buffer is required to safely transfer AP from real address mode to
|
||||||
|
protected mode or long mode, due to the fact that the buffer returned by
|
||||||
|
GetWakeupBuffer() may be marked as non-executable.
|
||||||
|
|
||||||
|
@param[in] BufferSize Wakeup transition buffer size.
|
||||||
|
|
||||||
|
@retval other Return wakeup transition buffer address below 4GB.
|
||||||
|
@retval 0 Cannot find free memory below 4GB.
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
GetModeTransitionBuffer (
|
||||||
|
IN UINTN BufferSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// PEI phase doesn't need to do such transition. So simply return 0.
|
||||||
|
//
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks APs status and updates APs status if needed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
CheckAndUpdateApsStatus (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize global data for MP support.
|
||||||
|
|
||||||
|
@param[in] CpuMpData The pointer to CPU MP Data structure.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
InitMpGlobalData (
|
||||||
|
IN CPU_MP_DATA *CpuMpData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SaveCpuMpData (CpuMpData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This service executes a caller provided function on all enabled APs.
|
||||||
|
|
||||||
|
@param[in] Procedure A pointer to the function to be run on
|
||||||
|
enabled APs of the system. See type
|
||||||
|
EFI_AP_PROCEDURE.
|
||||||
|
@param[in] SingleThread If TRUE, then all the enabled APs execute
|
||||||
|
the function specified by Procedure one by
|
||||||
|
one, in ascending order of processor handle
|
||||||
|
number. If FALSE, then all the enabled APs
|
||||||
|
execute the function specified by Procedure
|
||||||
|
simultaneously.
|
||||||
|
@param[in] WaitEvent The event created by the caller with CreateEvent()
|
||||||
|
service. If it is NULL, then execute in
|
||||||
|
blocking mode. BSP waits until all APs finish
|
||||||
|
or TimeoutInMicroSeconds expires. If it's
|
||||||
|
not NULL, then execute in non-blocking mode.
|
||||||
|
BSP requests the function specified by
|
||||||
|
Procedure to be started on all the enabled
|
||||||
|
APs, and go on executing immediately. If
|
||||||
|
all return from Procedure, or TimeoutInMicroSeconds
|
||||||
|
expires, this event is signaled. The BSP
|
||||||
|
can use the CheckEvent() or WaitForEvent()
|
||||||
|
services to check the state of event. Type
|
||||||
|
EFI_EVENT is defined in CreateEvent() in
|
||||||
|
the Unified Extensible Firmware Interface
|
||||||
|
Specification.
|
||||||
|
@param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
|
||||||
|
APs to return from Procedure, either for
|
||||||
|
blocking or non-blocking mode. Zero means
|
||||||
|
infinity. If the timeout expires before
|
||||||
|
all APs return from Procedure, then Procedure
|
||||||
|
on the failed APs is terminated. All enabled
|
||||||
|
APs are available for next function assigned
|
||||||
|
by MpInitLibStartupAllAPs() or
|
||||||
|
MPInitLibStartupThisAP().
|
||||||
|
If the timeout expires in blocking mode,
|
||||||
|
BSP returns EFI_TIMEOUT. If the timeout
|
||||||
|
expires in non-blocking mode, WaitEvent
|
||||||
|
is signaled with SignalEvent().
|
||||||
|
@param[in] ProcedureArgument The parameter passed into Procedure for
|
||||||
|
all APs.
|
||||||
|
@param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
|
||||||
|
if all APs finish successfully, then its
|
||||||
|
content is set to NULL. If not all APs
|
||||||
|
finish before timeout expires, then its
|
||||||
|
content is set to address of the buffer
|
||||||
|
holding handle numbers of the failed APs.
|
||||||
|
The buffer is allocated by MP Initialization
|
||||||
|
library, and it's the caller's responsibility to
|
||||||
|
free the buffer with FreePool() service.
|
||||||
|
In blocking mode, it is ready for consumption
|
||||||
|
when the call returns. In non-blocking mode,
|
||||||
|
it is ready when WaitEvent is signaled. The
|
||||||
|
list of failed CPU is terminated by
|
||||||
|
END_OF_CPU_LIST.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS In blocking mode, all APs have finished before
|
||||||
|
the timeout expired.
|
||||||
|
@retval EFI_SUCCESS In non-blocking mode, function has been dispatched
|
||||||
|
to all enabled APs.
|
||||||
|
@retval EFI_UNSUPPORTED A non-blocking mode request was made after the
|
||||||
|
UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
|
||||||
|
signaled.
|
||||||
|
@retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not
|
||||||
|
supported.
|
||||||
|
@retval EFI_DEVICE_ERROR Caller processor is AP.
|
||||||
|
@retval EFI_NOT_STARTED No enabled APs exist in the system.
|
||||||
|
@retval EFI_NOT_READY Any enabled APs are busy.
|
||||||
|
@retval EFI_NOT_READY MP Initialize Library is not initialized.
|
||||||
|
@retval EFI_TIMEOUT In blocking mode, the timeout expired before
|
||||||
|
all enabled APs have finished.
|
||||||
|
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MpInitLibStartupAllAPs (
|
||||||
|
IN EFI_AP_PROCEDURE Procedure,
|
||||||
|
IN BOOLEAN SingleThread,
|
||||||
|
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||||
|
IN UINTN TimeoutInMicroseconds,
|
||||||
|
IN VOID *ProcedureArgument OPTIONAL,
|
||||||
|
OUT UINTN **FailedCpuList OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (WaitEvent != NULL) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StartupAllCPUsWorker (
|
||||||
|
Procedure,
|
||||||
|
SingleThread,
|
||||||
|
TRUE,
|
||||||
|
NULL,
|
||||||
|
TimeoutInMicroseconds,
|
||||||
|
ProcedureArgument,
|
||||||
|
FailedCpuList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This service lets the caller get one enabled AP to execute a caller-provided
|
||||||
|
function.
|
||||||
|
|
||||||
|
@param[in] Procedure A pointer to the function to be run on the
|
||||||
|
designated AP of the system. See type
|
||||||
|
EFI_AP_PROCEDURE.
|
||||||
|
@param[in] ProcessorNumber The handle number of the AP. The range is
|
||||||
|
from 0 to the total number of logical
|
||||||
|
processors minus 1. The total number of
|
||||||
|
logical processors can be retrieved by
|
||||||
|
MpInitLibGetNumberOfProcessors().
|
||||||
|
@param[in] WaitEvent The event created by the caller with CreateEvent()
|
||||||
|
service. If it is NULL, then execute in
|
||||||
|
blocking mode. BSP waits until this AP finish
|
||||||
|
or TimeoutInMicroSeconds expires. If it's
|
||||||
|
not NULL, then execute in non-blocking mode.
|
||||||
|
BSP requests the function specified by
|
||||||
|
Procedure to be started on this AP,
|
||||||
|
and go on executing immediately. If this AP
|
||||||
|
return from Procedure or TimeoutInMicroSeconds
|
||||||
|
expires, this event is signaled. The BSP
|
||||||
|
can use the CheckEvent() or WaitForEvent()
|
||||||
|
services to check the state of event. Type
|
||||||
|
EFI_EVENT is defined in CreateEvent() in
|
||||||
|
the Unified Extensible Firmware Interface
|
||||||
|
Specification.
|
||||||
|
@param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
|
||||||
|
this AP to finish this Procedure, either for
|
||||||
|
blocking or non-blocking mode. Zero means
|
||||||
|
infinity. If the timeout expires before
|
||||||
|
this AP returns from Procedure, then Procedure
|
||||||
|
on the AP is terminated. The
|
||||||
|
AP is available for next function assigned
|
||||||
|
by MpInitLibStartupAllAPs() or
|
||||||
|
MpInitLibStartupThisAP().
|
||||||
|
If the timeout expires in blocking mode,
|
||||||
|
BSP returns EFI_TIMEOUT. If the timeout
|
||||||
|
expires in non-blocking mode, WaitEvent
|
||||||
|
is signaled with SignalEvent().
|
||||||
|
@param[in] ProcedureArgument The parameter passed into Procedure on the
|
||||||
|
specified AP.
|
||||||
|
@param[out] Finished If NULL, this parameter is ignored. In
|
||||||
|
blocking mode, this parameter is ignored.
|
||||||
|
In non-blocking mode, if AP returns from
|
||||||
|
Procedure before the timeout expires, its
|
||||||
|
content is set to TRUE. Otherwise, the
|
||||||
|
value is set to FALSE. The caller can
|
||||||
|
determine if the AP returned from Procedure
|
||||||
|
by evaluating this value.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS In blocking mode, specified AP finished before
|
||||||
|
the timeout expires.
|
||||||
|
@retval EFI_SUCCESS In non-blocking mode, the function has been
|
||||||
|
dispatched to specified AP.
|
||||||
|
@retval EFI_UNSUPPORTED A non-blocking mode request was made after the
|
||||||
|
UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
|
||||||
|
signaled.
|
||||||
|
@retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not
|
||||||
|
supported.
|
||||||
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
|
@retval EFI_TIMEOUT In blocking mode, the timeout expired before
|
||||||
|
the specified AP has finished.
|
||||||
|
@retval EFI_NOT_READY The specified AP is busy.
|
||||||
|
@retval EFI_NOT_READY MP Initialize Library is not initialized.
|
||||||
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
|
ProcessorNumber does not exist.
|
||||||
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
|
||||||
|
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MpInitLibStartupThisAP (
|
||||||
|
IN EFI_AP_PROCEDURE Procedure,
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||||
|
IN UINTN TimeoutInMicroseconds,
|
||||||
|
IN VOID *ProcedureArgument OPTIONAL,
|
||||||
|
OUT BOOLEAN *Finished OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (WaitEvent != NULL) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StartupThisAPWorker (
|
||||||
|
Procedure,
|
||||||
|
ProcessorNumber,
|
||||||
|
NULL,
|
||||||
|
TimeoutInMicroseconds,
|
||||||
|
ProcedureArgument,
|
||||||
|
Finished
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This service switches the requested AP to be the BSP from that point onward.
|
||||||
|
This service changes the BSP for all purposes. This call can only be performed
|
||||||
|
by the current BSP.
|
||||||
|
|
||||||
|
@param[in] ProcessorNumber The handle number of AP that is to become the new
|
||||||
|
BSP. The range is from 0 to the total number of
|
||||||
|
logical processors minus 1. The total number of
|
||||||
|
logical processors can be retrieved by
|
||||||
|
MpInitLibGetNumberOfProcessors().
|
||||||
|
@param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
|
||||||
|
enabled AP. Otherwise, it will be disabled.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS BSP successfully switched.
|
||||||
|
@retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
|
||||||
|
this service returning.
|
||||||
|
@retval EFI_UNSUPPORTED Switching the BSP is not supported.
|
||||||
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
|
ProcessorNumber does not exist.
|
||||||
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
|
||||||
|
a disabled AP.
|
||||||
|
@retval EFI_NOT_READY The specified AP is busy.
|
||||||
|
@retval EFI_NOT_READY MP Initialize Library is not initialized.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MpInitLibSwitchBSP (
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN BOOLEAN EnableOldBSP
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This service lets the caller enable or disable an AP from this point onward.
|
||||||
|
This service may only be called from the BSP.
|
||||||
|
|
||||||
|
@param[in] ProcessorNumber The handle number of AP.
|
||||||
|
The range is from 0 to the total number of
|
||||||
|
logical processors minus 1. The total number of
|
||||||
|
logical processors can be retrieved by
|
||||||
|
MpInitLibGetNumberOfProcessors().
|
||||||
|
@param[in] EnableAP Specifies the new state for the processor for
|
||||||
|
enabled, FALSE for disabled.
|
||||||
|
@param[in] HealthFlag If not NULL, a pointer to a value that specifies
|
||||||
|
the new health status of the AP. This flag
|
||||||
|
corresponds to StatusFlag defined in
|
||||||
|
EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
|
||||||
|
the PROCESSOR_HEALTH_STATUS_BIT is used. All other
|
||||||
|
bits are ignored. If it is NULL, this parameter
|
||||||
|
is ignored.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
|
||||||
|
@retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
|
||||||
|
prior to this service returning.
|
||||||
|
@retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
|
||||||
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
|
@retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
|
||||||
|
does not exist.
|
||||||
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
|
||||||
|
@retval EFI_NOT_READY MP Initialize Library is not initialized.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MpInitLibEnableDisableAP (
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
IN BOOLEAN EnableAP,
|
||||||
|
IN UINT32 *HealthFlag OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
# MP Initialize Library instance for PEI driver.
|
# MP Initialize Library instance for PEI driver.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@ -18,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
# The following information is for reference only and not required by the build tools.
|
# The following information is for reference only and not required by the build tools.
|
||||||
#
|
#
|
||||||
# VALID_ARCHITECTURES = IA32 X64
|
# VALID_ARCHITECTURES = IA32 X64 LOONGARCH64
|
||||||
#
|
#
|
||||||
|
|
||||||
[Sources.IA32]
|
[Sources.IA32]
|
||||||
@ -29,7 +30,7 @@
|
|||||||
X64/AmdSev.c
|
X64/AmdSev.c
|
||||||
X64/MpFuncs.nasm
|
X64/MpFuncs.nasm
|
||||||
|
|
||||||
[Sources.common]
|
[Sources.IA32, Sources.X64]
|
||||||
AmdSev.c
|
AmdSev.c
|
||||||
Microcode.c
|
Microcode.c
|
||||||
MpEqu.inc
|
MpEqu.inc
|
||||||
@ -38,6 +39,11 @@
|
|||||||
MpHandOff.h
|
MpHandOff.h
|
||||||
PeiMpLib.c
|
PeiMpLib.c
|
||||||
|
|
||||||
|
[Sources.LoongArch64]
|
||||||
|
LoongArch64/PeiMpLib.c
|
||||||
|
LoongArch64/MpLib.c
|
||||||
|
LoongArch64/MpLib.h
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
MdeModulePkg/MdeModulePkg.dec
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
@ -45,17 +51,19 @@
|
|||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
CcExitLib
|
|
||||||
CpuLib
|
CpuLib
|
||||||
HobLib
|
HobLib
|
||||||
LocalApicLib
|
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
MicrocodeLib
|
|
||||||
MtrrLib
|
|
||||||
PcdLib
|
PcdLib
|
||||||
PeiServicesLib
|
PeiServicesLib
|
||||||
SynchronizationLib
|
SynchronizationLib
|
||||||
|
|
||||||
|
[LibraryClasses.IA32, LibraryClasses.X64]
|
||||||
|
CcExitLib
|
||||||
|
LocalApicLib
|
||||||
|
MicrocodeLib
|
||||||
|
MtrrLib
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr ## CONSUMES
|
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr ## CONSUMES
|
||||||
@ -77,3 +85,6 @@
|
|||||||
[Guids]
|
[Guids]
|
||||||
gEdkiiS3SmmInitDoneGuid
|
gEdkiiS3SmmInitDoneGuid
|
||||||
gEdkiiMicrocodePatchHobGuid
|
gEdkiiMicrocodePatchHobGuid
|
||||||
|
|
||||||
|
[Guids.LoongArch64]
|
||||||
|
gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB
|
||||||
|
Loading…
x
Reference in New Issue
Block a user