From: "Chao Li" <lichao@loongson.cn>
To: devel@edk2.groups.io, Ray Ni <ray.ni@intel.com>,
Laszlo Ersek <lersek@redhat.com>
Cc: Eric Dong <eric.dong@intel.com>,
Rahul Kumar <rahul1.kumar@intel.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Baoqi Zhang <zhangbaoqi@loongson.cn>,
Dongyan Qian <qiandongyan@loongson.cn>
Subject: Re: [edk2-devel] [PATCH v8 16/37] UefiCpuPkg: Add CpuDxe driver for LoongArch64
Date: Wed, 31 Jan 2024 13:33:49 +0800 [thread overview]
Message-ID: <88147892-342c-468f-8af7-08ee6148d3dc@loongson.cn> (raw)
In-Reply-To: <17AF511F29808828.16460@groups.io>
[-- Attachment #1: Type: text/plain, Size: 71289 bytes --]
Hi Ray and Laszlo,
I would very much like to be merged into stable202302, the soft feature
deadline is 2024-02-05, so could you please hlep to review this patch as
soon as passable? Please...
Thanks,
Chao
On 2024/1/31 11:32, Chao Li wrote:
>
> Hi Ray,
>
> Can you please help to review this patch again?
>
> On 2024/1/26 14:29, Chao Li wrote:
>> Added LoongArch64 CPU driver into CpuDxe.
>>
>> BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=4584
>>
>> Cc: Eric Dong<eric.dong@intel.com>
>> 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>
>> Co-authored-by: Baoqi Zhang<zhangbaoqi@loongson.cn>
>> Co-authored-by: Dongyan Qian<qiandongyan@loongson.cn>
>> ---
>> UefiCpuPkg/CpuDxe/CpuDxe.inf | 23 +-
>> UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.c | 454 ++++++++++++++++++
>> UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.h | 288 ++++++++++++
>> UefiCpuPkg/CpuDxe/LoongArch64/CpuMp.c | 544 ++++++++++++++++++++++
>> UefiCpuPkg/CpuDxe/LoongArch64/Exception.c | 159 +++++++
>> 5 files changed, 1464 insertions(+), 4 deletions(-)
>> create mode 100644 UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.c
>> create mode 100644 UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.h
>> create mode 100644 UefiCpuPkg/CpuDxe/LoongArch64/CpuMp.c
>> create mode 100644 UefiCpuPkg/CpuDxe/LoongArch64/Exception.c
>>
>> diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
>> index 1d3e9f8cdb..18ebd2eb2c 100644
>> --- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
>> +++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
>> @@ -3,6 +3,7 @@
>> #
>> # Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
>> # Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
>> +# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
>> #
>> # SPDX-License-Identifier: BSD-2-Clause-Patent
>> #
>> @@ -22,17 +23,16 @@
>> MdeModulePkg/MdeModulePkg.dec
>> UefiCpuPkg/UefiCpuPkg.dec
>>
>> -[LibraryClasses]
>> +[LibraryClasses.common]
>> BaseLib
>> BaseMemoryLib
>> CpuLib
>> + CacheMaintenanceLib
>> DebugLib
>> DxeServicesTableLib
>> MemoryAllocationLib
>> - MtrrLib
>> UefiBootServicesTableLib
>> UefiDriverEntryPoint
>> - LocalApicLib
>> UefiLib
>> CpuExceptionHandlerLib
>> HobLib
>> @@ -41,7 +41,14 @@
>> TimerLib
>> PeCoffGetEntryPointLib
>>
>> -[Sources]
>> +[LibraryClasses.IA32, LibraryClasses.X64]
>> + LocalApicLib
>> + MtrrLib
>> +
>> +[LibraryClasses.LoongArch64]
>> + CpuMmuLib
>> +
>> +[Sources.IA32, Sources.X64]
>> CpuDxe.c
>> CpuDxe.h
>> CpuGdt.c
>> @@ -59,6 +66,13 @@
>> X64/CpuAsm.nasm
>> X64/PagingAttribute.c
>>
>> +[Sources.LoongArch64]
>> + CpuMp.h
>> + LoongArch64/CpuDxe.c
>> + LoongArch64/CpuMp.c
>> + LoongArch64/Exception.c
>> + LoongArch64/CpuDxe.h
>> +
>> [Protocols]
>> gEfiCpuArchProtocolGuid ## PRODUCES
>> gEfiMpServiceProtocolGuid ## PRODUCES
>> @@ -77,6 +91,7 @@
>> gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
>> gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
>> gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
>> + gUefiCpuPkgTokenSpaceGuid.PcdCpuExceptionVectorBaseAddress ## CONSUMES
>> gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## CONSUMES
>> gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## CONSUMES
>> gEfiMdeModulePkgTokenSpaceGuid.PcdTdxSharedBitMask ## CONSUMES
>> diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.c b/UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.c
>> new file mode 100644
>> index 0000000000..65ed0b3913
>> --- /dev/null
>> +++ b/UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.c
>> @@ -0,0 +1,454 @@
>> +/** @file CpuDxe.c
>> +
>> + CPU DXE Module to produce CPU ARCH Protocol.
>> +
>> + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
>> +
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +**/
>> +
>> +#include "CpuDxe.h"
>> +#include "CpuMp.h"
>> +#include <Guid/IdleLoopEvent.h>
>> +#include <Library/CpuMmuLib.h>
>> +#include <Library/TimerLib.h>
>> +#include <Register/LoongArch64/Csr.h>
>> +
>> +UINT64 mTimerPeriod = 0;
>> +
>> +/**
>> + IPI Interrupt Handler.
>> +
>> + @param InterruptType The type of interrupt that occurred
>> + @param SystemContext A pointer to the system context when the interrupt occurred
>> +**/
>> +VOID
>> +EFIAPI
>> +IpiInterruptHandler (
>> + IN EFI_EXCEPTION_TYPE InterruptType,
>> + IN EFI_SYSTEM_CONTEXT SystemContext
>> + );
>> +
>> +//
>> +// Globals used to initialize the protocol
>> +//
>> +EFI_HANDLE mCpuHandle = NULL;
>> +EFI_CPU_ARCH_PROTOCOL gCpu = {
>> + CpuFlushCpuDataCache,
>> + CpuEnableInterrupt,
>> + CpuDisableInterrupt,
>> + CpuGetInterruptState,
>> + CpuInit,
>> + CpuRegisterInterruptHandler,
>> + CpuGetTimerValue,
>> + CpuSetMemoryAttributes,
>> + 0, // NumberOfTimers
>> + 4, // DmaBufferAlignment
>> +};
>> +
>> +/**
>> + This function flushes the range of addresses from Start to Start+Length
>> + from the processor's data cache. If Start is not aligned to a cache line
>> + boundary, then the bytes before Start to the preceding cache line boundary
>> + are also flushed. If Start+Length is not aligned to a cache line boundary,
>> + then the bytes past Start+Length to the end of the next cache line boundary
>> + are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
>> + supported. If the data cache is fully coherent with all DMA operations, then
>> + this function can just return EFI_SUCCESS. If the processor does not support
>> + flushing a range of the data cache, then the entire data cache can be flushed.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> + @param Start The beginning physical address to flush from the processor's data
>> + cache.
>> + @param Length The number of bytes to flush from the processor's data cache. This
>> + function may flush more bytes than Length specifies depending upon
>> + the granularity of the flush operation that the processor supports.
>> + @param FlushType Specifies the type of flush operation to perform.
>> +
>> + @retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
>> + the processor's data cache.
>> + @retval EFI_INVALID_PARAMETER The processor does not support the cache flush type specified
>> + by FlushType.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuFlushCpuDataCache (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN EFI_PHYSICAL_ADDRESS Start,
>> + IN UINT64 Length,
>> + IN EFI_CPU_FLUSH_TYPE FlushType
>> + )
>> +{
>> + switch (FlushType) {
>> + case EfiCpuFlushTypeWriteBack:
>> + WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
>> + break;
>> + case EfiCpuFlushTypeInvalidate:
>> + InvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
>> + break;
>> + case EfiCpuFlushTypeWriteBackInvalidate:
>> + WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
>> + break;
>> + default:
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + This function enables interrupt processing by the processor.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> +
>> + @retval EFI_SUCCESS Interrupts are enabled on the processor.
>> + @retval EFI_DEVICE_ERROR Interrupts could not be enabled on the processor.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuEnableInterrupt (
>> + IN EFI_CPU_ARCH_PROTOCOL *This
>> + )
>> +{
>> + EnableInterrupts ();
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + This function disables interrupt processing by the processor.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> +
>> + @retval EFI_SUCCESS Interrupts are disabled on the processor.
>> + @retval EFI_DEVICE_ERROR Interrupts could not be disabled on the processor.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuDisableInterrupt (
>> + IN EFI_CPU_ARCH_PROTOCOL *This
>> + )
>> +{
>> + DisableInterrupts ();
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + This function retrieves the processor's current interrupt state a returns it in
>> + State. If interrupts are currently enabled, then TRUE is returned. If interrupts
>> + are currently disabled, then FALSE is returned.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> + @param State A pointer to the processor's current interrupt state. Set to TRUE if
>> + interrupts are enabled and FALSE if interrupts are disabled.
>> +
>> + @retval EFI_SUCCESS The processor's current interrupt state was returned in State.
>> + @retval EFI_INVALID_PARAMETER State is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuGetInterruptState (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + OUT BOOLEAN *State
>> + )
>> +{
>> + if (State == NULL) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + *State = GetInterruptState ();
>> + return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + This function generates an INIT on the processor. If this function succeeds, then the
>> + processor will be reset, and control will not be returned to the caller. If InitType is
>> + not supported by this processor, or the processor cannot programmatically generate an
>> + INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error
>> + occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> + @param InitType The type of processor INIT to perform.
>> +
>> + @retval EFI_SUCCESS The processor INIT was performed. This return code should never be seen.
>> + @retval EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported
>> + by this processor.
>> + @retval EFI_DEVICE_ERROR The processor INIT failed.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuInit (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN EFI_CPU_INIT_TYPE InitType
>> + )
>> +{
>> + return EFI_UNSUPPORTED;
>> +}
>> +
>> +/**
>> + Registers a function to be called from the CPU interrupt handler.
>> +
>> + @param This Protocol instance structure
>> + @param InterruptType Defines which interrupt to hook. IA-32
>> + valid range is 0x00 through 0xFF
>> + @param InterruptHandler A pointer to a function of type
>> + EFI_CPU_INTERRUPT_HANDLER that is called
>> + when a processor interrupt occurs. A null
>> + pointer is an error condition.
>> +
>> + @retval EFI_SUCCESS If handler installed or uninstalled.
>> + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler
>> + for InterruptType was previously installed.
>> + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for
>> + InterruptType was not previously installed.
>> + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType
>> + is not supported.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuRegisterInterruptHandler (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN EFI_EXCEPTION_TYPE InterruptType,
>> + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
>> + )
>> +{
>> + return RegisterInterruptHandler (InterruptType, InterruptHandler);
>> +}
>> +
>> +/**
>> + Returns a timer value from one of the CPU's internal timers. There is no
>> + inherent time interval between ticks but is a function of the CPU frequency.
>> +
>> + @param This - Protocol instance structure.
>> + @param TimerIndex - Specifies which CPU timer is requested.
>> + @param TimerValue - Pointer to the returned timer value.
>> + @param TimerPeriod - A pointer to the amount of time that passes
>> + in femtoseconds (10-15) for each increment
>> + of TimerValue. If TimerValue does not
>> + increment at a predictable rate, then 0 is
>> + returned. The amount of time that has
>> + passed between two calls to GetTimerValue()
>> + can be calculated with the formula
>> + (TimerValue2 - TimerValue1) * TimerPeriod.
>> + This parameter is optional and may be NULL.
>> +
>> + @retval EFI_SUCCESS - If the CPU timer count was returned.
>> + @retval EFI_UNSUPPORTED - If the CPU does not have any readable timers.
>> + @retval EFI_DEVICE_ERROR - If an error occurred while reading the timer.
>> + @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuGetTimerValue (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN UINT32 TimerIndex,
>> + OUT UINT64 *TimerValue,
>> + OUT UINT64 *TimerPeriod OPTIONAL
>> + )
>> +{
>> + UINT64 BeginValue;
>> + UINT64 EndValue;
>> +
>> + if (TimerValue == NULL) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + if (TimerIndex != 0) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + *TimerValue = AsmReadStableCounter ();
>> +
>> + if (TimerPeriod != NULL) {
>> + if (mTimerPeriod == 0) {
>> + //
>> + // Read time stamp counter before and after delay of 100 microseconds
>> + //
>> + BeginValue = AsmReadStableCounter ();
>> + MicroSecondDelay (100);
>> + EndValue = AsmReadStableCounter ();
>> + //
>> + // Calculate the actual frequency
>> + //
>> + mTimerPeriod = DivU64x64Remainder (
>> + MultU64x32 (
>> + 1000 * 1000 * 1000,
>> + 100
>> + ),
>> + EndValue - BeginValue,
>> + NULL
>> + );
>> + }
>> +
>> + *TimerPeriod = mTimerPeriod;
>> + }
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + This function modifies the attributes for the memory region specified by BaseAddress and
>> + Length from their current attributes to the attributes specified by Attributes.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> + @param BaseAddress The physical address that is the start address of a memory region.
>> + @param Length The size in bytes of the memory region.
>> + @param EfiAttributes The bit mask of attributes to set for the memory region.
>> +
>> + @retval EFI_SUCCESS The attributes were set for the memory region.
>> + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
>> + BaseAddress and Length cannot be modified.
>> + @retval EFI_INVALID_PARAMETER Length is zero.
>> + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
>> + the memory resource range.
>> + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
>> + resource range specified by BaseAddress and Length.
>> + The bit mask of attributes is not support for the memory resource
>> + range specified by BaseAddress and Length.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuSetMemoryAttributes (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN EFI_PHYSICAL_ADDRESS BaseAddress,
>> + IN UINT64 Length,
>> + IN UINT64 EfiAttributes
>> + )
>> +{
>> + EFI_STATUS Status;
>> + UINTN LoongArchAttributes;
>> + UINTN RegionBaseAddress;
>> + UINTN RegionLength;
>> + UINTN RegionLoongArchAttributes;
>> +
>> + RegionLength = Length;
>> + Status = EFI_SUCCESS;
>> +
>> + if ((BaseAddress & (EFI_PAGE_SIZE - 1)) != 0) {
>> + //
>> + // Minimum granularity is SIZE_4KB.
>> + //
>> + DEBUG ((
>> + DEBUG_INFO,
>> + "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum granularity is SIZE_4KB\n",
>> + BaseAddress,
>> + Length,
>> + EfiAttributes
>> + ));
>> +
>> + Status = EFI_UNSUPPORTED;
>> +
>> + return Status;
>> + }
>> +
>> + //
>> + // Convert the 'Attribute' into LoongArch Attribute
>> + //
>> + LoongArchAttributes = EfiAttributeConverse (EfiAttributes);
>> +
>> + //
>> + // Get the region starting from 'BaseAddress' and its 'Attribute'
>> + //
>> + RegionBaseAddress = BaseAddress;
>> + Status = GetMemoryRegionAttributes (
>> + RegionBaseAddress,
>> + &RegionLength,
>> + &RegionLoongArchAttributes
>> + );
>> +
>> + //
>> + // Data & Instruction Caches are flushed when we set new memory attributes.
>> + // So, we only set the attributes if the new region is different.
>> + //
>> + if ((Status == EFI_NOT_FOUND) || (RegionLoongArchAttributes != LoongArchAttributes) ||
>> + ((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))
>> + {
>> + Status = SetMemoryRegionAttributes (BaseAddress, Length, EfiAttributes, 0x0);
>> + }
>> +
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + return Status;
>> +}
>> +
>> +/**
>> + Callback function for idle events.
>> +
>> + @param Event Event whose notification function is being invoked.
>> + @param Context The pointer to the notification function's context,
>> + which is implementation-dependent.
>> +
>> +**/
>> +VOID
>> +EFIAPI
>> +IdleLoopEventCallback (
>> + IN EFI_EVENT Event,
>> + IN VOID *Context
>> + )
>> +{
>> + CpuSleep ();
>> +}
>> +
>> +/**
>> + Initialize the state information for the CPU Architectural Protocol.
>> +
>> + @param ImageHandle Image handle this driver.
>> + @param SystemTable Pointer to the System Table.
>> +
>> + @retval EFI_SUCCESS Thread can be successfully created
>> + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
>> + @retval EFI_DEVICE_ERROR Cannot create the thread
>> +
>> +**/
>> +EFI_STATUS
>> +InitializeCpu (
>> + IN EFI_HANDLE ImageHandle,
>> + IN EFI_SYSTEM_TABLE *SystemTable
>> + )
>> +{
>> + EFI_STATUS Status;
>> + EFI_EVENT IdleLoopEvent;
>> +
>> + InitializeExceptions (&gCpu);
>> +
>> + Status = gBS->InstallMultipleProtocolInterfaces (
>> + &mCpuHandle,
>> + &gEfiCpuArchProtocolGuid,
>> + &gCpu,
>> + NULL
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + Status = gCpu.RegisterInterruptHandler (
>> + &gCpu,
>> + EXCEPT_LOONGARCH_INT_IPI,
>> + IpiInterruptHandler
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + //
>> + // Setup a callback for idle events
>> + //
>> + Status = gBS->CreateEventEx (
>> + EVT_NOTIFY_SIGNAL,
>> + TPL_NOTIFY,
>> + IdleLoopEventCallback,
>> + NULL,
>> + &gIdleLoopEventGuid,
>> + &IdleLoopEvent
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + InitializeMpSupport ();
>> +
>> + return Status;
>> +}
>> diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.h b/UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.h
>> new file mode 100644
>> index 0000000000..8bfbfa3442
>> --- /dev/null
>> +++ b/UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.h
>> @@ -0,0 +1,288 @@
>> +/** @file CpuDxe.c
>> +
>> + CPU DXE Module to produce CPU ARCH Protocol.
>> +
>> + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
>> +
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +**/
>> +
>> +#ifndef CPU_DXE_H_
>> +#define CPU_DXE_H_
>> +
>> +#include <Uefi.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/CacheMaintenanceLib.h>
>> +#include <Library/CpuLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/DxeServicesTableLib.h>
>> +#include <Library/MpInitLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/PeCoffGetEntryPointLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +
>> +#include <Guid/DebugImageInfoTable.h>
>> +#include <Protocol/Cpu.h>
>> +#include <Protocol/DebugSupport.h>
>> +#include <Protocol/LoadedImage.h>
>> +
>> +//
>> +// For coding convenience, define the maximum valid
>> +// LoongArch exception.
>> +// Since UEFI V2.11, it will be present in DebugSupport.h.
>> +//
>> +#define MAX_LOONGARCH_EXCEPTION 64
>> +
>> +/*
>> + This function flushes the range of addresses from Start to Start+Length
>> + from the processor's data cache. If Start is not aligned to a cache line
>> + boundary, then the bytes before Start to the preceding cache line boundary
>> + are also flushed. If Start+Length is not aligned to a cache line boundary,
>> + then the bytes past Start+Length to the end of the next cache line boundary
>> + are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
>> + supported. If the data cache is fully coherent with all DMA operations, then
>> + this function can just return EFI_SUCCESS. If the processor does not support
>> + flushing a range of the data cache, then the entire data cache can be flushed.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> + @param Start The beginning physical address to flush from the processor's data
>> + cache.
>> + @param Length The number of bytes to flush from the processor's data cache. This
>> + function may flush more bytes than Length specifies depending upon
>> + the granularity of the flush operation that the processor supports.
>> + @param FlushType Specifies the type of flush operation to perform.
>> +
>> + @retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
>> + the processor's data cache.
>> + @retval EFI_UNSUPPORTEDT The processor does not support the cache flush type specified
>> + by FlushType.
>> + @retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
>> + from the processor's data cache.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuFlushCpuDataCache (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN EFI_PHYSICAL_ADDRESS Start,
>> + IN UINT64 Length,
>> + IN EFI_CPU_FLUSH_TYPE FlushType
>> + );
>> +
>> +/**
>> + This function enables interrupt processing by the processor.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> +
>> + @retval EFI_SUCCESS Interrupts are enabled on the processor.
>> + @retval EFI_DEVICE_ERROR Interrupts could not be enabled on the processor.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuEnableInterrupt (
>> + IN EFI_CPU_ARCH_PROTOCOL *This
>> + );
>> +
>> +/**
>> + This function disables interrupt processing by the processor.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> +
>> + @retval EFI_SUCCESS Interrupts are disabled on the processor.
>> + @retval EFI_DEVICE_ERROR Interrupts could not be disabled on the processor.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuDisableInterrupt (
>> + IN EFI_CPU_ARCH_PROTOCOL *This
>> + );
>> +
>> +/**
>> + This function retrieves the processor's current interrupt state a returns it in
>> + State. If interrupts are currently enabled, then TRUE is returned. If interrupts
>> + are currently disabled, then FALSE is returned.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> + @param State A pointer to the processor's current interrupt state. Set to TRUE if
>> + interrupts are enabled and FALSE if interrupts are disabled.
>> +
>> + @retval EFI_SUCCESS The processor's current interrupt state was returned in State.
>> + @retval EFI_INVALID_PARAMETER State is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuGetInterruptState (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + OUT BOOLEAN *State
>> + );
>> +
>> +/**
>> + This function generates an INIT on the processor. If this function succeeds, then the
>> + processor will be reset, and control will not be returned to the caller. If InitType is
>> + not supported by this processor, or the processor cannot programmatically generate an
>> + INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error
>> + occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> + @param InitType The type of processor INIT to perform.
>> +
>> + @retval EFI_SUCCESS The processor INIT was performed. This return code should never be seen.
>> + @retval EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported
>> + by this processor.
>> + @retval EFI_DEVICE_ERROR The processor INIT failed.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuInit (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN EFI_CPU_INIT_TYPE InitType
>> + );
>> +
>> +/**
>> + Registers a function to be called from the CPU interrupt handler.
>> +
>> + @param This Protocol instance structure
>> + @param InterruptType Defines which interrupt to hook. IA-32
>> + valid range is 0x00 through 0xFF
>> + @param InterruptHandler A pointer to a function of type
>> + EFI_CPU_INTERRUPT_HANDLER that is called
>> + when a processor interrupt occurs. A null
>> + pointer is an error condition.
>> +
>> + @retval EFI_SUCCESS If handler installed or uninstalled.
>> + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler
>> + for InterruptType was previously installed.
>> + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for
>> + InterruptType was not previously installed.
>> + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType
>> + is not supported.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuRegisterInterruptHandler (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN EFI_EXCEPTION_TYPE InterruptType,
>> + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
>> + );
>> +
>> +/**
>> + Returns a timer value from one of the CPU's internal timers. There is no
>> + inherent time interval between ticks but is a function of the CPU frequency.
>> +
>> + @param This - Protocol instance structure.
>> + @param TimerIndex - Specifies which CPU timer is requested.
>> + @param TimerValue - Pointer to the returned timer value.
>> + @param TimerPeriod - A pointer to the amount of time that passes
>> + in femtoseconds (10-15) for each increment
>> + of TimerValue. If TimerValue does not
>> + increment at a predictable rate, then 0 is
>> + returned. The amount of time that has
>> + passed between two calls to GetTimerValue()
>> + can be calculated with the formula
>> + (TimerValue2 - TimerValue1) * TimerPeriod.
>> + This parameter is optional and may be NULL.
>> +
>> + @retval EFI_SUCCESS - If the CPU timer count was returned.
>> + @retval EFI_UNSUPPORTED - If the CPU does not have any readable timers.
>> + @retval EFI_DEVICE_ERROR - If an error occurred while reading the timer.
>> + @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuGetTimerValue (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN UINT32 TimerIndex,
>> + OUT UINT64 *TimerValue,
>> + OUT UINT64 *TimerPeriod OPTIONAL
>> + );
>> +
>> +/**
>> + This function registers and enables the handler specified by InterruptHandler for a processor
>> + interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
>> + handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
>> + The installed handler is called once for each processor interrupt or exception.
>> +
>> + @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
>> + are enabled and FALSE if interrupts are disabled.
>> + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
>> + when a processor interrupt occurs. If this parameter is NULL, then the handler
>> + will be uninstalled.
>> +
>> + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
>> + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
>> + previously installed.
>> + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
>> + previously installed.
>> + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
>> +
>> +**/
>> +EFI_STATUS
>> +RegisterInterruptHandler (
>> + IN EFI_EXCEPTION_TYPE InterruptType,
>> + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
>> + );
>> +
>> +/**
>> + This function modifies the attributes for the memory region specified by BaseAddress and
>> + Length from their current attributes to the attributes specified by Attributes.
>> +
>> + @param This The EFI_CPU_ARCH_PROTOCOL instance.
>> + @param BaseAddress The physical address that is the start address of a memory region.
>> + @param Length The size in bytes of the memory region.
>> + @param Attributes The bit mask of attributes to set for the memory region.
>> +
>> + @retval EFI_SUCCESS The attributes were set for the memory region.
>> + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
>> + BaseAddress and Length cannot be modified.
>> + @retval EFI_INVALID_PARAMETER Length is zero.
>> + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
>> + the memory resource range.
>> + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
>> + resource range specified by BaseAddress and Length.
>> + The bit mask of attributes is not support for the memory resource
>> + range specified by BaseAddress and Length.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +CpuSetMemoryAttributes (
>> + IN EFI_CPU_ARCH_PROTOCOL *This,
>> + IN EFI_PHYSICAL_ADDRESS BaseAddress,
>> + IN UINT64 Length,
>> + IN UINT64 Attributes
>> + );
>> +
>> +/**
>> + Initialize interrupt handling for DXE phase.
>> +
>> + @param Cpu A pointer of EFI_CPU_ARCH_PROTOCOL instance.
>> +
>> + @return VOID.
>> +
>> +**/
>> +VOID
>> +InitializeExceptions (
>> + IN EFI_CPU_ARCH_PROTOCOL *gCpu
>> + );
>> +
>> +/**
>> + Converts EFI Attributes to corresponding architecture Attributes.
>> +
>> + @param[in] EfiAttributes Efi Attributes.
>> +
>> + @retval Corresponding architecture attributes.
>> +**/
>> +UINTN
>> +EFIAPI
>> +EfiAttributeConverse (
>> + IN UINTN EfiAttributes
>> + );
>> +
>> +#endif // CPU_DXE_H_
>> diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/CpuMp.c b/UefiCpuPkg/CpuDxe/LoongArch64/CpuMp.c
>> new file mode 100644
>> index 0000000000..3325914e53
>> --- /dev/null
>> +++ b/UefiCpuPkg/CpuDxe/LoongArch64/CpuMp.c
>> @@ -0,0 +1,544 @@
>> +/** @file
>> + CPU DXE Module to produce CPU MP Protocol.
>> +
>> + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
>> +
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +**/
>> +
>> +#include "CpuDxe.h"
>> +#include "CpuMp.h"
>> +
>> +EFI_HANDLE mMpServiceHandle = NULL;
>> +UINTN mNumberOfProcessors = 1;
>> +
>> +EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
>> + GetNumberOfProcessors,
>> + GetProcessorInfo,
>> + StartupAllAPs,
>> + StartupThisAP,
>> + SwitchBSP,
>> + EnableDisableAP,
>> + WhoAmI
>> +};
>> +
>> +/**
>> + This service retrieves the number of logical processor in the platform
>> + and the number of those logical processors that are enabled on this boot.
>> + This service may only be called from the BSP.
>> +
>> + This function is used to retrieve the following information:
>> + - The number of logical processors that are present in the system.
>> + - The number of enabled logical processors in the system at the instant
>> + this call is made.
>> +
>> + Because MP Service Protocol provides services to enable and disable processors
>> + dynamically, the number of enabled logical processors may vary during the
>> + course of a boot session.
>> +
>> + If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
>> + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
>> + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
>> + is returned in NumberOfProcessors, the number of currently enabled processor
>> + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
>> +
>> + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
>> + instance.
>> + @param[out] NumberOfProcessors Pointer to the total number of logical
>> + processors in the system, including the BSP
>> + and disabled APs.
>> + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
>> + processors that exist in system, including
>> + the BSP.
>> +
>> + @retval EFI_SUCCESS The number of logical processors and enabled
>> + logical processors was retrieved.
>> + @retval EFI_DEVICE_ERROR The calling processor is an AP.
>> + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
>> + @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +GetNumberOfProcessors (
>> + IN EFI_MP_SERVICES_PROTOCOL *This,
>> + OUT UINTN *NumberOfProcessors,
>> + OUT UINTN *NumberOfEnabledProcessors
>> + )
>> +{
>> + if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + return MpInitLibGetNumberOfProcessors (
>> + NumberOfProcessors,
>> + NumberOfEnabledProcessors
>> + );
>> +}
>> +
>> +/**
>> + Gets detailed MP-related information on the requested processor at the
>> + instant this call is made. This service may only be called from the BSP.
>> +
>> + This service retrieves detailed MP-related information about any processor
>> + on the platform. Note the following:
>> + - The processor information may change during the course of a boot session.
>> + - The information presented here is entirely MP related.
>> +
>> + Information regarding the number of caches and their sizes, frequency of operation,
>> + slot numbers is all considered platform-related information and is not provided
>> + by this service.
>> +
>> + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
>> + instance.
>> + @param[in] ProcessorNumber The handle number of processor.
>> + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
>> + the requested processor is deposited.
>> +
>> + @retval EFI_SUCCESS Processor information was returned.
>> + @retval EFI_DEVICE_ERROR The calling processor is an AP.
>> + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
>> + @retval EFI_NOT_FOUND The processor with the handle specified by
>> + ProcessorNumber does not exist in the platform.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +GetProcessorInfo (
>> + IN EFI_MP_SERVICES_PROTOCOL *This,
>> + IN UINTN ProcessorNumber,
>> + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
>> + )
>> +{
>> + return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);
>> +}
>> +
>> +/**
>> + This service executes a caller provided function on all enabled APs. APs can
>> + run either simultaneously or one at a time in sequence. This service supports
>> + both blocking and non-blocking requests. The non-blocking requests use EFI
>> + events so the BSP can detect when the APs have finished. This service may only
>> + be called from the BSP.
>> +
>> + This function is used to dispatch all the enabled APs to the function specified
>> + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
>> + immediately and Procedure is not started on any AP.
>> +
>> + If SingleThread is TRUE, all the enabled APs execute the function specified by
>> + Procedure one by one, in ascending order of processor handle number. Otherwise,
>> + all the enabled APs execute the function specified by Procedure simultaneously.
>> +
>> + If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
>> + APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking
>> + mode, and the BSP returns from this service without waiting for APs. If a
>> + non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
>> + is signaled, then EFI_UNSUPPORTED must be returned.
>> +
>> + If the timeout specified by TimeoutInMicroseconds expires before all APs return
>> + from Procedure, then Procedure on the failed APs is terminated. All enabled APs
>> + are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
>> + and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
>> + content points to the list of processor handle numbers in which Procedure was
>> + terminated.
>> +
>> + Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
>> + to make sure that the nature of the code that is executed on the BSP and the
>> + dispatched APs is well controlled. The MP Services Protocol does not guarantee
>> + that the Procedure function is MP-safe. Hence, the tasks that can be run in
>> + parallel are limited to certain independent tasks and well-controlled exclusive
>> + code. EFI services and protocols may not be called by APs unless otherwise
>> + specified.
>> +
>> + In blocking execution mode, BSP waits until all APs finish or
>> + TimeoutInMicroseconds expires.
>> +
>> + In non-blocking execution mode, BSP is freed to return to the caller and then
>> + proceed to the next task without having to wait for APs. The following
>> + sequence needs to occur in a non-blocking execution mode:
>> +
>> + -# The caller that intends to use this MP Services Protocol in non-blocking
>> + mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
>> + invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
>> + is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
>> + the function specified by Procedure to be started on all the enabled APs,
>> + and releases the BSP to continue with other tasks.
>> + -# The caller can use the CheckEvent() and WaitForEvent() services to check
>> + the state of the WaitEvent created in step 1.
>> + -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
>> + Service signals WaitEvent by calling the EFI SignalEvent() function. If
>> + FailedCpuList is not NULL, its content is available when WaitEvent is
>> + signaled. If all APs returned from Procedure prior to the timeout, then
>> + FailedCpuList is set to NULL. If not all APs return from Procedure before
>> + the timeout, then FailedCpuList is filled in with the list of the failed
>> + APs. The buffer is allocated by MP Service Protocol using AllocatePool().
>> + It is the caller's responsibility to free the buffer with FreePool() service.
>> + -# This invocation of SignalEvent() function informs the caller that invoked
>> + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
>> + the specified task or a timeout occurred. The contents of FailedCpuList
>> + can be examined to determine which APs did not complete the specified task
>> + prior to the timeout.
>> +
>> + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
>> + instance.
>> + @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 EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
>> + or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
>> + 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 Service Protocol,
>> + 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_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_TIMEOUT In blocking mode, the timeout expired before
>> + all enabled APs have finished.
>> + @retval EFI_INVALID_PARAMETER Procedure is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +StartupAllAPs (
>> + IN EFI_MP_SERVICES_PROTOCOL *This,
>> + IN EFI_AP_PROCEDURE Procedure,
>> + IN BOOLEAN SingleThread,
>> + IN EFI_EVENT WaitEvent OPTIONAL,
>> + IN UINTN TimeoutInMicroseconds,
>> + IN VOID *ProcedureArgument OPTIONAL,
>> + OUT UINTN **FailedCpuList OPTIONAL
>> + )
>> +{
>> + return MpInitLibStartupAllAPs (
>> + Procedure,
>> + SingleThread,
>> + WaitEvent,
>> + TimeoutInMicroseconds,
>> + ProcedureArgument,
>> + FailedCpuList
>> + );
>> +}
>> +
>> +/**
>> + This service lets the caller get one enabled AP to execute a caller-provided
>> + function. The caller can request the BSP to either wait for the completion
>> + of the AP or just proceed with the next task by using the EFI event mechanism.
>> + See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
>> + execution support. This service may only be called from the BSP.
>> +
>> + This function is used to dispatch one enabled AP to the function specified by
>> + Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
>> + is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
>> + TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
>> + BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
>> + is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
>> + then EFI_UNSUPPORTED must be returned.
>> +
>> + If the timeout specified by TimeoutInMicroseconds expires before the AP returns
>> + from Procedure, then execution of Procedure by the AP is terminated. The AP is
>> + available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
>> + EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
>> +
>> + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
>> + instance.
>> + @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
>> + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
>> + @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 EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
>> + or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
>> + 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_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_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
>> +StartupThisAP (
>> + IN EFI_MP_SERVICES_PROTOCOL *This,
>> + IN EFI_AP_PROCEDURE Procedure,
>> + IN UINTN ProcessorNumber,
>> + IN EFI_EVENT WaitEvent OPTIONAL,
>> + IN UINTN TimeoutInMicroseconds,
>> + IN VOID *ProcedureArgument OPTIONAL,
>> + OUT BOOLEAN *Finished OPTIONAL
>> + )
>> +{
>> + return MpInitLibStartupThisAP (
>> + Procedure,
>> + ProcessorNumber,
>> + WaitEvent,
>> + 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.
>> +
>> + This service switches the requested AP to be the BSP from that point onward.
>> + This service changes the BSP for all purposes. The new BSP can take over the
>> + execution of the old BSP and continue seamlessly from where the old one left
>> + off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
>> + is signaled.
>> +
>> + If the BSP cannot be switched prior to the return from this service, then
>> + EFI_UNSUPPORTED must be returned.
>> +
>> + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
>> + @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
>> + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
>> + @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.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +SwitchBSP (
>> + IN EFI_MP_SERVICES_PROTOCOL *This,
>> + IN UINTN ProcessorNumber,
>> + IN BOOLEAN EnableOldBSP
>> + )
>> +{
>> + return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);
>> +}
>> +
>> +/**
>> + This service lets the caller enable or disable an AP from this point onward.
>> + This service may only be called from the BSP.
>> +
>> + This service allows the caller enable or disable an AP from this point onward.
>> + The caller can optionally specify the health status of the AP by Health. If
>> + an AP is being disabled, then the state of the disabled AP is implementation
>> + dependent. If an AP is enabled, then the implementation must guarantee that a
>> + complete initialization sequence is performed on the AP, so the AP is in a state
>> + that is compatible with an MP operating system. This service may not be supported
>> + after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
>> +
>> + If the enable or disable AP operation cannot be completed prior to the return
>> + from this service, then EFI_UNSUPPORTED must be returned.
>> +
>> + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
>> + @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
>> + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
>> + @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.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +EnableDisableAP (
>> + IN EFI_MP_SERVICES_PROTOCOL *This,
>> + IN UINTN ProcessorNumber,
>> + IN BOOLEAN EnableAP,
>> + IN UINT32 *HealthFlag OPTIONAL
>> + )
>> +{
>> + return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);
>> +}
>> +
>> +/**
>> + This return the handle number for the calling processor. This service may be
>> + called from the BSP and APs.
>> +
>> + This service returns the processor handle number for the calling processor.
>> + The returned value is in the range from 0 to the total number of logical
>> + processors minus 1. The total number of logical processors can be retrieved
>> + with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
>> + called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
>> + is returned. Otherwise, the current processors handle number is returned in
>> + ProcessorNumber, and EFI_SUCCESS is returned.
>> +
>> + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
>> + @param[out] ProcessorNumber Pointer to 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
>> + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
>> +
>> + @retval EFI_SUCCESS The current processor handle number was returned
>> + in ProcessorNumber.
>> + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +WhoAmI (
>> + IN EFI_MP_SERVICES_PROTOCOL *This,
>> + OUT UINTN *ProcessorNumber
>> + )
>> +{
>> + return MpInitLibWhoAmI (ProcessorNumber);
>> +}
>> +
>> +/**
>> + Initialize Multi-processor support.
>> +**/
>> +VOID
>> +InitializeMpSupport (
>> + VOID
>> + )
>> +{
>> + EFI_STATUS Status;
>> + UINTN NumberOfProcessors;
>> + UINTN NumberOfEnabledProcessors;
>> +
>> + //
>> + // Wakeup APs to do initialization
>> + //
>> + Status = MpInitLibInitialize ();
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors);
>> + mNumberOfProcessors = NumberOfProcessors;
>> + DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mNumberOfProcessors));
>> +
>> + Status = gBS->InstallMultipleProtocolInterfaces (
>> + &mMpServiceHandle,
>> + &gEfiMpServiceProtocolGuid,
>> + &mMpServicesTemplate,
>> + NULL
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +}
>> diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c b/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c
>> new file mode 100644
>> index 0000000000..96def89936
>> --- /dev/null
>> +++ b/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c
>> @@ -0,0 +1,159 @@
>> +/** @file Exception.c
>> +
>> + CPU DXE Module initialization exception instance.
>> +
>> + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
>> +
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +**/
>> +
>> +#include "CpuDxe.h"
>> +#include <Guid/VectorHandoffTable.h>
>> +#include <Library/CpuExceptionHandlerLib.h>
>> +#include <Register/LoongArch64/Csr.h>
>> +
>> +VOID
>> +ExceptionEntryStart (
>> + VOID
>> + );
>> +
>> +VOID
>> +ExceptionEntryEnd (
>> + VOID
>> + );
>> +
>> +/**
>> + This function registers and enables the handler specified by InterruptHandler for a processor
>> + interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
>> + handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
>> + The installed handler is called once for each processor interrupt or exception.
>> +
>> + @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
>> + are enabled and FALSE if interrupts are disabled.
>> + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
>> + when a processor interrupt occurs. If this parameter is NULL, then the handler
>> + will be uninstalled.
>> +
>> + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
>> + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
>> + previously installed.
>> + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
>> + previously installed.
>> + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
>> +
>> +**/
>> +EFI_STATUS
>> +RegisterInterruptHandler (
>> + IN EFI_EXCEPTION_TYPE InterruptType,
>> + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
>> + )
>> +{
>> + return (EFI_STATUS)RegisterCpuInterruptHandler (InterruptType, InterruptHandler);
>> +}
>> +
>> +/**
>> + Update the exception start entry code.
>> +
>> + @retval EFI_SUCCESS Update the exception start entry code down.
>> + @retval EFI_OUT_OF_RESOURCES The start entry code size out of bounds.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +UpdateExceptionStartEntry (
>> + VOID
>> + )
>> +{
>> + EFI_PHYSICAL_ADDRESS ExceptionStartEntry;
>> + UINTN VectorLength;
>> + UINTN MaxLength;
>> + UINTN MaxSizeOfVector;
>> +
>> + VectorLength = (UINTN)ExceptionEntryEnd - (UINTN)ExceptionEntryStart;
>> +
>> + //
>> + // A vector is up to 512 bytes.
>> + //
>> + MaxSizeOfVector = 512;
>> + MaxLength = (MAX_LOONGARCH_EXCEPTION + MAX_LOONGARCH_INTERRUPT) * MaxSizeOfVector;
>> +
>> + if (VectorLength > MaxLength) {
>> + return EFI_OUT_OF_RESOURCES;
>> + }
>> +
>> + ExceptionStartEntry = PcdGet64 (PcdCpuExceptionVectorBaseAddress);
>> +
>> + InvalidateInstructionCacheRange ((VOID *)ExceptionStartEntry, VectorLength);
>> + CopyMem ((VOID *)ExceptionStartEntry, (VOID *)ExceptionEntryStart, VectorLength);
>> + InvalidateInstructionCacheRange ((VOID *)ExceptionStartEntry, VectorLength);
>> + InvalidateDataCache ();
>> +
>> + //
>> + // If PcdCpuExceptionVectorBaseAddress is not used during SEC and PEI stages, the exception
>> + // base addres is set to PcdCpuExceptionVectorBaseAddress.
>> + //
>> + if (CsrRead (LOONGARCH_CSR_EBASE) != ExceptionStartEntry) {
>> + SetExceptionBaseAddress (ExceptionStartEntry);
>> + }
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + Initialize interrupt handling for DXE phase.
>> +
>> + @param Cpu A pointer of EFI_CPU_ARCH_PROTOCOL instance.
>> +
>> + @return VOID.
>> +
>> +**/
>> +VOID
>> +InitializeExceptions (
>> + IN EFI_CPU_ARCH_PROTOCOL *Cpu
>> + )
>> +{
>> + EFI_STATUS Status;
>> + EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
>> + EFI_VECTOR_HANDOFF_INFO *VectorInfo;
>> + BOOLEAN IrqEnabled;
>> +
>> + VectorInfo = (EFI_VECTOR_HANDOFF_INFO *)NULL;
>> + Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **)&VectorInfoList);
>> +
>> + if ((Status == EFI_SUCCESS) && (VectorInfoList != NULL)) {
>> + VectorInfo = VectorInfoList;
>> + }
>> +
>> + //
>> + // Disable interrupts
>> + //
>> + Cpu->GetInterruptState (Cpu, &IrqEnabled);
>> + if (IrqEnabled) {
>> + Cpu->DisableInterrupt (Cpu);
>> + }
>> +
>> + //
>> + // Update the Exception Start Entry code to point into CpuDxe.
>> + //
>> + Status = UpdateExceptionStartEntry ();
>> + if (EFI_ERROR (Status)) {
>> + DebugPrint (EFI_D_ERROR, "[%a]: Exception start entry code out of bounds!\n", __func__);
>> + ASSERT_EFI_ERROR (Status);
>> + }
>> +
>> + //
>> + // Intialize the CpuExceptionHandlerLib so we take over the exception vector table from the DXE Core
>> + //
>> + Status = InitializeCpuExceptionHandlers (VectorInfo);
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + //
>> + // Enable interrupts
>> + //
>> + DebugPrint (EFI_D_INFO, "InitializeExceptions,IrqEnabled = %x\n", IrqEnabled);
>> + if (!IrqEnabled) {
>> + Status = Cpu->EnableInterrupt (Cpu);
>> + }
>> +
>> + ASSERT_EFI_ERROR (Status);
>> +}
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114863): https://edk2.groups.io/g/devel/message/114863
Mute This Topic: https://groups.io/mt/104070187/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
[-- Attachment #2: Type: text/html, Size: 69178 bytes --]
prev parent reply other threads:[~2024-01-31 5:33 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-26 6:27 [edk2-devel] [PATCH v8 00/37] Enable LoongArch virtual machine in edk2 Chao Li
2024-01-26 6:27 ` [edk2-devel] [PATCH v8 01/37] MdePkg: Add the header file named Csr.h for LoongArch64 Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 02/37] MdePkg: Add LoongArch64 FPU function set into BaseCpuLib Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 03/37] MdePkg: Add LoongArch64 exception function set into BaseLib Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 04/37] MdePkg: Add LoongArch64 local interrupt " Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 05/37] MdePkg: Add LoongArch Cpucfg function Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 06/37] MdePkg: Add read stable counter operation for LoongArch Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 07/37] MdePkg: Add CSR " Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 08/37] MdePkg: Add IOCSR " Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 09/37] MdePkg: Add a new library named PeiServicesTablePointerLibKs0 Chao Li
2024-01-26 6:28 ` [edk2-devel] [PATCH v8 10/37] MdePkg: Add some comments for LoongArch exceptions Chao Li
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 11/37] UefiCpuPkg: Add LoongArch64 CPU Timer instance Chao Li
2024-02-02 3:24 ` Ni, Ray
2024-02-02 3:38 ` Chao Li
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 12/37] UefiCpuPkg: Add CPU exception library for LoongArch Chao Li
2024-02-02 3:30 ` Ni, Ray
2024-02-02 3:44 ` Chao Li
2024-02-02 4:30 ` Ni, Ray
2024-03-08 8:02 ` Chao Li
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 13/37] UefiCpuPkg: Add CpuMmuLib.h to UefiCpuPkg Chao Li
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 14/37] UefiCpuPkg: Add CpuMmuLib " Chao Li
2024-01-31 9:47 ` Laszlo Ersek
2024-02-01 7:57 ` Chao Li
2024-02-01 22:46 ` Laszlo Ersek
2024-02-02 3:30 ` Chao Li
2024-02-02 3:33 ` Ni, Ray
2024-02-02 3:50 ` Chao Li
2024-02-02 4:30 ` Ni, Ray
2024-03-01 1:26 ` Chao Li
2024-03-01 11:27 ` Laszlo Ersek
2024-03-04 3:39 ` Chao Li
2024-03-05 9:26 ` Laszlo Ersek
2024-03-05 11:50 ` Chao Li
2024-03-05 12:09 ` Laszlo Ersek
2024-03-05 12:12 ` Chao Li
[not found] ` <17B87F9FA8D0E543.14067@groups.io>
2024-03-01 1:53 ` Chao Li
2024-01-31 10:33 ` Pedro Falcato
2024-01-31 13:41 ` Laszlo Ersek
2024-01-31 17:46 ` Pedro Falcato
2024-02-01 3:05 ` Chao Li
2024-02-01 19:36 ` Pedro Falcato
2024-02-01 23:02 ` Laszlo Ersek
2024-02-02 15:14 ` Leif Lindholm
2024-02-04 2:58 ` Chao Li
[not found] ` <17B0898B4883051D.13964@groups.io>
2024-02-06 2:57 ` Chao Li
2024-02-06 14:32 ` Laszlo Ersek
2024-02-06 16:45 ` Pedro Falcato
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 15/37] UefiCpuPkg: Add multiprocessor library for LoongArch64 Chao Li
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 16/37] UefiCpuPkg: Add CpuDxe driver " Chao Li
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 17/37] EmbeddedPkg: Add PcdPrePiCpuIoSize width for LOONGARCH64 Chao Li
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 18/37] ArmVirtPkg: Move PCD of FDT base address and FDT padding to OvmfPkg Chao Li
2024-02-01 23:20 ` Laszlo Ersek
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 19/37] UefiCpuPkg: Add a new CPU IO 2 driver named CpuMmio2Dxe Chao Li
2024-01-26 6:29 ` [edk2-devel] [PATCH v8 20/37] ArmVirtPkg: Enable CpuMmio2Dxe Chao Li
2024-02-01 22:19 ` Laszlo Ersek
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 21/37] OvmfPkg/RiscVVirt: " Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 22/37] OvmfPkg/RiscVVirt: Remove PciCpuIo2Dxe from RiscVVirt Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 23/37] ArmVirtPkg: Move the FdtSerialPortAddressLib to OvmfPkg Chao Li
2024-01-29 19:27 ` Laszlo Ersek
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 24/37] ArmVirtPkg: Move two PCD variables into OvmfPkg Chao Li
2024-01-29 19:49 ` Laszlo Ersek
2024-01-30 1:24 ` Chao Li
2024-01-30 16:45 ` Laszlo Ersek
2024-01-31 1:30 ` Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 25/37] ArmVirtPkg: Move PlatformBootManagerLib to OvmfPkg Chao Li
2024-01-29 19:51 ` Laszlo Ersek
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 26/37] OvmfPkg/LoongArchVirt: Add stable timer driver Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 27/37] OvmfPkg/LoongArchVirt: Add a NULL library named CollectApResouceLibNull Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 28/37] OvmfPkg/LoongArchVirt: Add serial port hook library Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 29/37] OvmfPkg/LoongArchVirt: Add the early serial port output library Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 30/37] OvmfPkg/LoongArchVirt: Add real time clock library Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 31/37] OvmfPkg/LoongArchVirt: Add NorFlashQemuLib Chao Li
2024-01-26 6:30 ` [edk2-devel] [PATCH v8 32/37] OvmfPkg/LoongArchVirt: Add FdtQemuFwCfgLib Chao Li
2024-01-26 6:31 ` [edk2-devel] [PATCH v8 33/37] OvmfPkg/LoongArchVirt: Add reset system library Chao Li
2024-01-26 6:31 ` [edk2-devel] [PATCH v8 34/37] OvmfPkg/LoongArchVirt: Support SEC phase Chao Li
2024-01-26 6:31 ` [edk2-devel] [PATCH v8 35/37] OvmfPkg/LoongArchVirt: Support PEI phase Chao Li
2024-01-26 6:31 ` [edk2-devel] [PATCH v8 36/37] OvmfPkg/LoongArchVirt: Add build file Chao Li
2024-01-26 6:31 ` [edk2-devel] [PATCH v8 37/37] OvmfPkg/LoongArchVirt: Add self introduction file Chao Li
[not found] ` <17ADD1D5A196C454.24595@groups.io>
2024-01-31 3:30 ` [edk2-devel] [PATCH v8 11/37] UefiCpuPkg: Add LoongArch64 CPU Timer instance Chao Li
[not found] ` <17AF510405DE784C.15701@groups.io>
2024-01-31 5:28 ` Chao Li
2024-01-31 10:47 ` Laszlo Ersek
[not found] ` <17ADD1D7001C37D6.11113@groups.io>
2024-01-31 3:31 ` [edk2-devel] [PATCH v8 12/37] UefiCpuPkg: Add CPU exception library for LoongArch Chao Li
[not found] ` <17AF510933F4B8FA.15701@groups.io>
2024-01-31 5:29 ` Chao Li
[not found] ` <17ADD1D9CA04F352.11113@groups.io>
2024-01-31 3:31 ` [edk2-devel] [PATCH v8 14/37] UefiCpuPkg: Add CpuMmuLib to UefiCpuPkg Chao Li
[not found] ` <17AF511188DE2475.15701@groups.io>
2024-01-31 5:32 ` Chao Li
[not found] ` <17ADD1DB56FC4702.24595@groups.io>
2024-01-31 3:32 ` [edk2-devel] [PATCH v8 15/37] UefiCpuPkg: Add multiprocessor library for LoongArch64 Chao Li
[not found] ` <17AF511741BD9C8B.15701@groups.io>
2024-01-31 5:33 ` Chao Li
[not found] ` <17ADD1DCBDD4B7FE.11113@groups.io>
2024-01-31 3:32 ` [edk2-devel] [PATCH v8 16/37] UefiCpuPkg: Add CpuDxe driver " Chao Li
[not found] ` <17AF511F29808828.16460@groups.io>
2024-01-31 5:33 ` Chao Li [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=88147892-342c-468f-8af7-08ee6148d3dc@loongson.cn \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox