mirror of https://github.com/acidanthera/audk.git
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.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
##
|
||||
|
@ -18,7 +19,7 @@
|
|||
#
|
||||
# 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]
|
||||
|
@ -31,7 +32,7 @@
|
|||
X64/CreatePageTable.c
|
||||
X64/MpFuncs.nasm
|
||||
|
||||
[Sources.common]
|
||||
[Sources.IA32, Sources.X64]
|
||||
AmdSev.c
|
||||
DxeMpLib.c
|
||||
Microcode.c
|
||||
|
@ -40,6 +41,11 @@
|
|||
MpLib.h
|
||||
MpHandOff.h
|
||||
|
||||
[Sources.LoongArch64]
|
||||
LoongArch64/DxeMpLib.c
|
||||
LoongArch64/MpLib.c
|
||||
LoongArch64/MpLib.h
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
@ -47,18 +53,20 @@
|
|||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
CcExitLib
|
||||
CpuLib
|
||||
DebugAgentLib
|
||||
HobLib
|
||||
LocalApicLib
|
||||
MemoryAllocationLib
|
||||
MicrocodeLib
|
||||
MtrrLib
|
||||
PcdLib
|
||||
SynchronizationLib
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[LibraryClasses.IA32, LibraryClasses.X64]
|
||||
CcExitLib
|
||||
LocalApicLib
|
||||
MicrocodeLib
|
||||
MtrrLib
|
||||
|
||||
[LibraryClasses.X64]
|
||||
CpuPageTableLib
|
||||
|
||||
|
@ -70,6 +78,9 @@
|
|||
gEfiEventLegacyBootGuid ## SOMETIMES_CONSUMES ## Event
|
||||
gEdkiiMicrocodePatchHobGuid ## SOMETIMES_CONSUMES ## HOB
|
||||
|
||||
[Guids.LoongArch64]
|
||||
gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
|
||||
|
|
|
@ -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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
##
|
||||
|
@ -18,7 +19,7 @@
|
|||
#
|
||||
# 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]
|
||||
|
@ -29,7 +30,7 @@
|
|||
X64/AmdSev.c
|
||||
X64/MpFuncs.nasm
|
||||
|
||||
[Sources.common]
|
||||
[Sources.IA32, Sources.X64]
|
||||
AmdSev.c
|
||||
Microcode.c
|
||||
MpEqu.inc
|
||||
|
@ -38,6 +39,11 @@
|
|||
MpHandOff.h
|
||||
PeiMpLib.c
|
||||
|
||||
[Sources.LoongArch64]
|
||||
LoongArch64/PeiMpLib.c
|
||||
LoongArch64/MpLib.c
|
||||
LoongArch64/MpLib.h
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
@ -45,17 +51,19 @@
|
|||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
CcExitLib
|
||||
CpuLib
|
||||
HobLib
|
||||
LocalApicLib
|
||||
MemoryAllocationLib
|
||||
MicrocodeLib
|
||||
MtrrLib
|
||||
PcdLib
|
||||
PeiServicesLib
|
||||
SynchronizationLib
|
||||
|
||||
[LibraryClasses.IA32, LibraryClasses.X64]
|
||||
CcExitLib
|
||||
LocalApicLib
|
||||
MicrocodeLib
|
||||
MtrrLib
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr ## CONSUMES
|
||||
|
@ -77,3 +85,6 @@
|
|||
[Guids]
|
||||
gEdkiiS3SmmInitDoneGuid
|
||||
gEdkiiMicrocodePatchHobGuid
|
||||
|
||||
[Guids.LoongArch64]
|
||||
gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB
|
||||
|
|
Loading…
Reference in New Issue