mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 07:34:06 +02:00
UefiCpuPkg: Add CPU exception library for LoongArch
Added LoongArch exception handler into CpuExceptionHandlerLib. 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> Co-authored-by: Baoqi Zhang <zhangbaoqi@loongson.cn> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
parent
439030bc37
commit
7750468c37
@ -2,6 +2,7 @@
|
|||||||
# CPU Exception Handler library instance for DXE modules.
|
# CPU Exception Handler library instance for DXE modules.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@ -18,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
# The following information is for reference only and not required by the build tools.
|
# The following information is for reference only and not required by the build tools.
|
||||||
#
|
#
|
||||||
# VALID_ARCHITECTURES = IA32 X64
|
# VALID_ARCHITECTURES = IA32 X64 LOONGARCH64
|
||||||
#
|
#
|
||||||
|
|
||||||
[Sources.Ia32]
|
[Sources.Ia32]
|
||||||
@ -32,12 +33,19 @@
|
|||||||
X64/ArchInterruptDefs.h
|
X64/ArchInterruptDefs.h
|
||||||
X64/ExceptionHandlerAsm.nasm
|
X64/ExceptionHandlerAsm.nasm
|
||||||
|
|
||||||
[Sources.common]
|
[Sources.Ia32, Sources.X64]
|
||||||
CpuExceptionCommon.h
|
CpuExceptionCommon.h
|
||||||
CpuExceptionCommon.c
|
CpuExceptionCommon.c
|
||||||
DxeException.c
|
DxeException.c
|
||||||
PeiDxeSmmCpuException.c
|
PeiDxeSmmCpuException.c
|
||||||
|
|
||||||
|
[Sources.LoongArch64]
|
||||||
|
LoongArch/DxeExceptionLib.c
|
||||||
|
LoongArch/ExceptionCommon.h
|
||||||
|
LoongArch/ExceptionCommon.c
|
||||||
|
LoongArch/LoongArch64/ArchExceptionHandler.c
|
||||||
|
LoongArch/LoongArch64/ExceptionHandlerAsm.S | GCC
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
|
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
|
||||||
@ -51,16 +59,21 @@
|
|||||||
MdeModulePkg/MdeModulePkg.dec
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
UefiCpuPkg/UefiCpuPkg.dec
|
UefiCpuPkg/UefiCpuPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses.common]
|
||||||
BaseLib
|
BaseLib
|
||||||
CcExitLib
|
|
||||||
DebugLib
|
DebugLib
|
||||||
LocalApicLib
|
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
PeCoffGetEntryPointLib
|
PeCoffGetEntryPointLib
|
||||||
PrintLib
|
PrintLib
|
||||||
SerialPortLib
|
SerialPortLib
|
||||||
SynchronizationLib
|
SynchronizationLib
|
||||||
|
|
||||||
|
[LibraryClasses.Ia32, LibraryClasses.X64]
|
||||||
|
CcExitLib
|
||||||
|
LocalApicLib
|
||||||
|
|
||||||
|
[LibraryClasses.LoongArch64]
|
||||||
|
CpuLib
|
||||||
|
|
||||||
[BuildOptions]
|
[BuildOptions]
|
||||||
XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT
|
XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT
|
||||||
|
@ -0,0 +1,198 @@
|
|||||||
|
/** @file DxeExceptionLib.c
|
||||||
|
|
||||||
|
LoongArch exception library implemenation for DXE modules.
|
||||||
|
|
||||||
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/CpuExceptionHandlerLib.h>
|
||||||
|
#include <Library/CpuLib.h>
|
||||||
|
#include <Library/CacheMaintenanceLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/SerialPortLib.h>
|
||||||
|
#include <Protocol/DebugSupport.h>
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
|
||||||
|
#include "ExceptionCommon.h"
|
||||||
|
|
||||||
|
EFI_EXCEPTION_CALLBACK ExternalInterruptHandler[MAX_LOONGARCH_INTERRUPT + 1] = { 0 };
|
||||||
|
EFI_EXCEPTION_CALLBACK ExceptionHandler[MAX_LOONGARCH_EXCEPTION + 1] = { 0 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
Registers a function to be called from the processor interrupt or exception handler.
|
||||||
|
|
||||||
|
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
|
||||||
|
RegisterCpuInterruptHandler (
|
||||||
|
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||||
|
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_EXCEPTION_TYPE ExceptionType;
|
||||||
|
|
||||||
|
ExceptionType = InterruptType & CSR_ESTAT_EXC;
|
||||||
|
|
||||||
|
if (ExceptionType != 0) {
|
||||||
|
//
|
||||||
|
// Exception >>= CSR_ESTAT_EXC_SHIFT, convert to ECODE
|
||||||
|
//
|
||||||
|
ExceptionType >>= CSR_ESTAT_EXC_SHIFT;
|
||||||
|
|
||||||
|
if (ExceptionType > EXCEPT_LOONGARCH_FPE) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((InterruptHandler == NULL) && (ExceptionHandler[InterruptType] == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((InterruptHandler != NULL) && (ExceptionHandler[ExceptionType] != NULL)) {
|
||||||
|
return EFI_ALREADY_STARTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExceptionHandler[ExceptionType] = InterruptHandler;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Interrupt
|
||||||
|
//
|
||||||
|
if (InterruptType > MAX_LOONGARCH_INTERRUPT) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((InterruptHandler == NULL) && (ExternalInterruptHandler[InterruptType] == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((InterruptHandler != NULL) && (ExternalInterruptHandler[InterruptType] != NULL)) {
|
||||||
|
return EFI_ALREADY_STARTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalInterruptHandler[InterruptType] = InterruptHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Common exception handler.
|
||||||
|
|
||||||
|
@param ExceptionType Exception type.
|
||||||
|
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
CommonExceptionHandler (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||||
|
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_EXCEPTION_TYPE InterruptType;
|
||||||
|
|
||||||
|
if (ExceptionType == EXCEPT_LOONGARCH_INT) {
|
||||||
|
//
|
||||||
|
// Interrupt
|
||||||
|
//
|
||||||
|
InterruptType = GetInterruptType (SystemContext);
|
||||||
|
if (InterruptType == 0xFF) {
|
||||||
|
ExceptionType = InterruptType;
|
||||||
|
} else {
|
||||||
|
if ((ExternalInterruptHandler != NULL) && (ExternalInterruptHandler[InterruptType] != NULL)) {
|
||||||
|
ExternalInterruptHandler[InterruptType](InterruptType, SystemContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ExceptionType == EXCEPT_LOONGARCH_FPD) {
|
||||||
|
EnableFloatingPointUnits ();
|
||||||
|
InitializeFloatingPointUnits ();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Exception
|
||||||
|
//
|
||||||
|
ExceptionType >>= CSR_ESTAT_EXC_SHIFT;
|
||||||
|
if ((ExceptionHandler != NULL) && (ExceptionHandler[ExceptionType] != NULL)) {
|
||||||
|
ExceptionHandler[ExceptionType](ExceptionType, SystemContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Only the TLB refill exception use the same entry point as normal exceptions.
|
||||||
|
//
|
||||||
|
if (CsrRead (LOONGARCH_CSR_TLBRERA) & 0x1) {
|
||||||
|
ExceptionType = mExceptionKnownNameNum - 1; // Use only to dump the exception context.
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultExceptionHandler (ExceptionType, SystemContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes all CPU exceptions entries and provides the default exception handlers.
|
||||||
|
|
||||||
|
Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
|
||||||
|
persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
|
||||||
|
If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
|
||||||
|
If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
|
||||||
|
|
||||||
|
@param[in] VectorInfo Pointer to reserved vector list.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
|
||||||
|
with default exception handlers.
|
||||||
|
@retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
|
||||||
|
@retval EFI_UNSUPPORTED This function is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
InitializeCpuExceptionHandlers (
|
||||||
|
IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Setup separate stacks for certain exception handlers.
|
||||||
|
If the input Buffer and BufferSize are both NULL, use global variable if possible.
|
||||||
|
|
||||||
|
@param[in] Buffer Point to buffer used to separate exception stack.
|
||||||
|
@param[in, out] BufferSize On input, it indicates the byte size of Buffer.
|
||||||
|
If the size is not enough, the return status will
|
||||||
|
be EFI_BUFFER_TOO_SMALL, and output BufferSize
|
||||||
|
will be the size it needs.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The stacks are assigned successfully.
|
||||||
|
@retval EFI_UNSUPPORTED This function is not supported.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL This BufferSize is too small.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
InitializeSeparateExceptionStacks (
|
||||||
|
IN VOID *Buffer,
|
||||||
|
IN OUT UINTN *BufferSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
@ -0,0 +1,171 @@
|
|||||||
|
/** @file DxeExceptionLib.c
|
||||||
|
|
||||||
|
CPU Exception Handler Library common functions.
|
||||||
|
|
||||||
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/PeCoffGetEntryPointLib.h>
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
|
#include <Library/SerialPortLib.h>
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
#include "ExceptionCommon.h"
|
||||||
|
|
||||||
|
CONST CHAR8 mExceptionReservedStr[] = "Reserved";
|
||||||
|
CONST CHAR8 *mExceptionNameStr[] = {
|
||||||
|
"#INT - Interrupt(CSR.ECFG.VS=0)",
|
||||||
|
"#PIL - Page invalid exception for Load option",
|
||||||
|
"#PIS - Page invalid exception for Store operation",
|
||||||
|
"#PIF - Page invalid exception for Fetch operation",
|
||||||
|
"#PME - Page modification exception",
|
||||||
|
"#PNR - Page non-readable exception",
|
||||||
|
"#PNX - Page non-executable exception",
|
||||||
|
"#PPI - Page privilege level illegal exception",
|
||||||
|
"#ADE - Address error exception",
|
||||||
|
"#ALE - Address alignment fault exception",
|
||||||
|
"#BCE - Bound check exception",
|
||||||
|
"#SYS - System call exception",
|
||||||
|
"#BRK - Beeakpoint exception",
|
||||||
|
"#INE - Instruction non-defined exception",
|
||||||
|
"#IPE - Instruction privilege error exception",
|
||||||
|
"#FPD - Floating-point instruction disable exception",
|
||||||
|
"#SXD - 128-bit vector (SIMD instructions) expansion instruction disable exception",
|
||||||
|
"#ASXD - 256-bit vector (Advanced SIMD instructions) expansion instruction disable exception",
|
||||||
|
"#FPE - Floating-Point error exception",
|
||||||
|
"#WPE - WatchPoint Exception for Fetch watchpoint or Memory load/store watchpoint",
|
||||||
|
"#BTD - Binary Translation expansion instruction Disable exception",
|
||||||
|
"#BTE - Binary Translation related exceptions",
|
||||||
|
"#GSPR - Guest Sensitive Privileged Resource exception",
|
||||||
|
"#HVC - HyperVisor Call exception",
|
||||||
|
"#GCXC - Guest CSR Software/Hardware Change exception",
|
||||||
|
"#TBR - TLB refill exception" // !!! NOTICE: Because the TLB refill exception is not instructed in ECODE, so the TLB refill exception must be the last one!
|
||||||
|
};
|
||||||
|
|
||||||
|
INTN mExceptionKnownNameNum = (sizeof (mExceptionNameStr) / sizeof (CHAR8 *));
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get ASCII format string exception name by exception type.
|
||||||
|
|
||||||
|
@param ExceptionType Exception type.
|
||||||
|
|
||||||
|
@return ASCII format string exception name.
|
||||||
|
|
||||||
|
**/
|
||||||
|
CONST CHAR8 *
|
||||||
|
GetExceptionNameStr (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((UINTN)ExceptionType < mExceptionKnownNameNum) {
|
||||||
|
return mExceptionNameStr[ExceptionType];
|
||||||
|
} else {
|
||||||
|
return mExceptionReservedStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Prints a message to the serial port.
|
||||||
|
|
||||||
|
@param Format Format string for the message to print.
|
||||||
|
@param ... Variable argument list whose contents are accessed
|
||||||
|
based on the format string specified by Format.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
InternalPrintMessage (
|
||||||
|
IN CONST CHAR8 *Format,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
|
||||||
|
VA_LIST Marker;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert the message to an ASCII String
|
||||||
|
//
|
||||||
|
VA_START (Marker, Format);
|
||||||
|
AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
|
||||||
|
VA_END (Marker);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send the print string to a Serial Port
|
||||||
|
//
|
||||||
|
SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find and display image base address and return image base and its entry point.
|
||||||
|
|
||||||
|
@param CurrentEra Current instruction pointer.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
DumpModuleImageInfo (
|
||||||
|
IN UINTN CurrentEra
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN Pe32Data;
|
||||||
|
VOID *PdbPointer;
|
||||||
|
VOID *EntryPoint;
|
||||||
|
|
||||||
|
Pe32Data = PeCoffSearchImageBase (CurrentEra);
|
||||||
|
if (Pe32Data == 0) {
|
||||||
|
InternalPrintMessage ("!!!! Can't find image information. !!!!\n");
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Find Image Base entry point
|
||||||
|
//
|
||||||
|
Status = PeCoffLoaderGetEntryPoint ((VOID *)Pe32Data, &EntryPoint);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
EntryPoint = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalPrintMessage ("!!!! Find image based on IP(0x%x) ", CurrentEra);
|
||||||
|
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data);
|
||||||
|
if (PdbPointer != NULL) {
|
||||||
|
InternalPrintMessage ("%a", PdbPointer);
|
||||||
|
} else {
|
||||||
|
InternalPrintMessage ("(No PDB) ");
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalPrintMessage (
|
||||||
|
" (ImageBase=%016lp, EntryPoint=%016p) !!!!\n",
|
||||||
|
(VOID *)Pe32Data,
|
||||||
|
EntryPoint
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Default exception handler.
|
||||||
|
|
||||||
|
@param ExceptionType Exception type.
|
||||||
|
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
DefaultExceptionHandler (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||||
|
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Initialize the serial port before dumping.
|
||||||
|
//
|
||||||
|
SerialPortInitialize ();
|
||||||
|
//
|
||||||
|
// Display ExceptionType, CPU information and Image information
|
||||||
|
//
|
||||||
|
DumpImageAndCpuContent (ExceptionType, SystemContext);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enter a dead loop.
|
||||||
|
//
|
||||||
|
CpuDeadLoop ();
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
/** @file DxeExceptionLib.h
|
||||||
|
|
||||||
|
Common header file for CPU Exception Handler Library.
|
||||||
|
|
||||||
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef EXCEPTION_COMMON_H_
|
||||||
|
#define EXCEPTION_COMMON_H_
|
||||||
|
|
||||||
|
#define MAX_DEBUG_MESSAGE_LENGTH 0x100
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
extern INTN mExceptionKnownNameNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get ASCII format string exception name by exception type.
|
||||||
|
|
||||||
|
@param[in] ExceptionType Exception type.
|
||||||
|
|
||||||
|
@return ASCII format string exception name.
|
||||||
|
|
||||||
|
**/
|
||||||
|
CONST CHAR8 *
|
||||||
|
GetExceptionNameStr (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Prints a message to the serial port.
|
||||||
|
|
||||||
|
@param[in] Format Format string for the message to print.
|
||||||
|
@param[in] ... Variable argument list whose contents are accessed
|
||||||
|
based on the format string specified by Format.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
InternalPrintMessage (
|
||||||
|
IN CONST CHAR8 *Format,
|
||||||
|
...
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find and display image base address and return image base and its entry point.
|
||||||
|
|
||||||
|
@param[in] CurrentEip Current instruction pointer.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
DumpModuleImageInfo (
|
||||||
|
IN UINTN CurrentEip
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Default exception handler.
|
||||||
|
|
||||||
|
@param[in] ExceptionType Exception type.
|
||||||
|
@param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
DefaultExceptionHandler (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||||
|
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Display CPU information.
|
||||||
|
|
||||||
|
@param[in] ExceptionType Exception type.
|
||||||
|
@param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
DumpImageAndCpuContent (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||||
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get exception types
|
||||||
|
|
||||||
|
@param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
@return Exception type.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_EXCEPTION_TYPE
|
||||||
|
EFIAPI
|
||||||
|
GetExceptionType (
|
||||||
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get Common interrupt types
|
||||||
|
|
||||||
|
@param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
@return Interrupt type.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_EXCEPTION_TYPE
|
||||||
|
EFIAPI
|
||||||
|
GetInterruptType (
|
||||||
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,268 @@
|
|||||||
|
/** @file ArchExceptionHandler.c
|
||||||
|
|
||||||
|
LoongArch64 CPU Exception Handler.
|
||||||
|
|
||||||
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
#include "ExceptionCommon.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get Exception Type
|
||||||
|
|
||||||
|
@param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
@return LoongArch64 exception type.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_EXCEPTION_TYPE
|
||||||
|
EFIAPI
|
||||||
|
GetExceptionType (
|
||||||
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_EXCEPTION_TYPE ExceptionType;
|
||||||
|
|
||||||
|
ExceptionType = (SystemContext.SystemContextLoongArch64->ESTAT & CSR_ESTAT_EXC);
|
||||||
|
return ExceptionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get Interrupt Type
|
||||||
|
|
||||||
|
@param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
@return LoongArch64 intrrupt type.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_EXCEPTION_TYPE
|
||||||
|
EFIAPI
|
||||||
|
GetInterruptType (
|
||||||
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_EXCEPTION_TYPE InterruptType;
|
||||||
|
|
||||||
|
for (InterruptType = 0; InterruptType <= EXCEPT_LOONGARCH_INT_IPI; InterruptType++) {
|
||||||
|
if (SystemContext.SystemContextLoongArch64->ESTAT & (1 << InterruptType)) {
|
||||||
|
//
|
||||||
|
// 0 - EXCEPT_LOONGARCH_INT_SIP0
|
||||||
|
// 1 - EXCEPT_LOONGARCH_INT_SIP1
|
||||||
|
// 2 - EXCEPT_LOONGARCH_INT_IP0
|
||||||
|
// 3 - EXCEPT_LOONGARCH_INT_IP1
|
||||||
|
// 4 - EXCEPT_LOONGARCH_INT_IP2
|
||||||
|
// 5 - EXCEPT_LOONGARCH_INT_IP3
|
||||||
|
// 6 - EXCEPT_LOONGARCH_INT_IP4
|
||||||
|
// 7 - EXCEPT_LOONGARCH_INT_IP5
|
||||||
|
// 8 - EXCEPT_LOONGARCH_INT_IP6
|
||||||
|
// 9 - EXCEPT_LOONGARCH_INT_IP7
|
||||||
|
// 10 - EXCEPT_LOONGARCH_INT_PMC
|
||||||
|
// 11 - EXCEPT_LOONGARCH_INT_TIMER
|
||||||
|
// 12 - EXCEPT_LOONGARCH_INT_IPI
|
||||||
|
// Greater than EXCEPT_LOONGARCH_INI_IPI is currently invalid.
|
||||||
|
//
|
||||||
|
return InterruptType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Invalid IRQ
|
||||||
|
//
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Display CPU information.
|
||||||
|
|
||||||
|
@param ExceptionType Exception type.
|
||||||
|
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
DumpCpuContext (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||||
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
InternalPrintMessage (
|
||||||
|
"\n!!!! LoongArch64 Exception Type - %02x(%a) !!!!\n",
|
||||||
|
ExceptionType,
|
||||||
|
GetExceptionNameStr (ExceptionType)
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dump TLB refill ERA and BADV
|
||||||
|
//
|
||||||
|
if (ExceptionType == (mExceptionKnownNameNum - 1)) {
|
||||||
|
InternalPrintMessage ("TLB refill ERA 0x%llx\n", (CsrRead (LOONGARCH_CSR_TLBRERA) & (~0x3ULL)));
|
||||||
|
InternalPrintMessage ("TLB refill BADV 0x%llx\n", CsrRead (LOONGARCH_CSR_TLBRBADV));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dump the general registers
|
||||||
|
//
|
||||||
|
InternalPrintMessage (
|
||||||
|
"Zero - 0x%016lx, RA - 0x%016lx, TP - 0x%016lx, SP - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->R0,
|
||||||
|
SystemContext.SystemContextLoongArch64->R1,
|
||||||
|
SystemContext.SystemContextLoongArch64->R2,
|
||||||
|
SystemContext.SystemContextLoongArch64->R3
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
" A0 - 0x%016lx, A1 - 0x%016lx, A2 - 0x%016lx, A3 - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->R4,
|
||||||
|
SystemContext.SystemContextLoongArch64->R5,
|
||||||
|
SystemContext.SystemContextLoongArch64->R6,
|
||||||
|
SystemContext.SystemContextLoongArch64->R7
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
" A4 - 0x%016lx, A5 - 0x%016lx, A6 - 0x%016lx, A7 - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->R8,
|
||||||
|
SystemContext.SystemContextLoongArch64->R9,
|
||||||
|
SystemContext.SystemContextLoongArch64->R10,
|
||||||
|
SystemContext.SystemContextLoongArch64->R11
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
" T0 - 0x%016lx, T1 - 0x%016lx, T2 - 0x%016lx, T3 - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->R12,
|
||||||
|
SystemContext.SystemContextLoongArch64->R13,
|
||||||
|
SystemContext.SystemContextLoongArch64->R14,
|
||||||
|
SystemContext.SystemContextLoongArch64->R15
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
" T4 - 0x%016lx, T5 - 0x%016lx, T6 - 0x%016lx, T7 - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->R16,
|
||||||
|
SystemContext.SystemContextLoongArch64->R17,
|
||||||
|
SystemContext.SystemContextLoongArch64->R18,
|
||||||
|
SystemContext.SystemContextLoongArch64->R19
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
" T8 - 0x%016lx, R21 - 0x%016lx, FP - 0x%016lx, S0 - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->R20,
|
||||||
|
SystemContext.SystemContextLoongArch64->R21,
|
||||||
|
SystemContext.SystemContextLoongArch64->R22,
|
||||||
|
SystemContext.SystemContextLoongArch64->R23
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
" S1 - 0x%016lx, S2 - 0x%016lx, S3 - 0x%016lx, S4 - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->R24,
|
||||||
|
SystemContext.SystemContextLoongArch64->R25,
|
||||||
|
SystemContext.SystemContextLoongArch64->R26,
|
||||||
|
SystemContext.SystemContextLoongArch64->R27
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
" S5 - 0x%016lx, S6 - 0x%016lx, S7 - 0x%016lx, S8 - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->R28,
|
||||||
|
SystemContext.SystemContextLoongArch64->R29,
|
||||||
|
SystemContext.SystemContextLoongArch64->R30,
|
||||||
|
SystemContext.SystemContextLoongArch64->R31
|
||||||
|
);
|
||||||
|
InternalPrintMessage ("\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dump the CSR registers
|
||||||
|
//
|
||||||
|
InternalPrintMessage (
|
||||||
|
"CRMD - 0x%016lx, PRMD - 0x%016lx, EUEN - 0x%016lx, MISC - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->CRMD,
|
||||||
|
SystemContext.SystemContextLoongArch64->PRMD,
|
||||||
|
SystemContext.SystemContextLoongArch64->EUEN,
|
||||||
|
SystemContext.SystemContextLoongArch64->MISC
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
"ECFG - 0x%016lx, ESTAT - 0x%016lx, ERA - 0x%016lx, BADV - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->ECFG,
|
||||||
|
SystemContext.SystemContextLoongArch64->ESTAT,
|
||||||
|
SystemContext.SystemContextLoongArch64->ERA,
|
||||||
|
SystemContext.SystemContextLoongArch64->BADV
|
||||||
|
);
|
||||||
|
InternalPrintMessage (
|
||||||
|
"BADI - 0x%016lx\n",
|
||||||
|
SystemContext.SystemContextLoongArch64->BADI
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Display CPU information.
|
||||||
|
|
||||||
|
@param ExceptionType Exception type.
|
||||||
|
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
DumpImageAndCpuContent (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||||
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DumpCpuContext (ExceptionType, SystemContext);
|
||||||
|
|
||||||
|
if (ExceptionType == (mExceptionKnownNameNum - 1)) {
|
||||||
|
//
|
||||||
|
// Dump TLB refill image info
|
||||||
|
//
|
||||||
|
DumpModuleImageInfo ((CsrRead (LOONGARCH_CSR_TLBRERA) & (~0x3ULL)));
|
||||||
|
} else {
|
||||||
|
DumpModuleImageInfo (SystemContext.SystemContextLoongArch64->ERA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN ResumeVector;
|
||||||
|
UINTN Parameter;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear interrupt.
|
||||||
|
//
|
||||||
|
IoCsrWrite32 (LOONGARCH_IOCSR_IPI_CLEAR, IoCsrRead32 (LOONGARCH_IOCSR_IPI_STATUS));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the resume vector and parameter if populated.
|
||||||
|
//
|
||||||
|
ResumeVector = IoCsrRead64 (LOONGARCH_IOCSR_MBUF0);
|
||||||
|
Parameter = IoCsrRead64 (LOONGARCH_IOCSR_MBUF3);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean up current processor mailbox 0 and mailbox 3.
|
||||||
|
//
|
||||||
|
IoCsrWrite64 (LOONGARCH_IOCSR_MBUF0, 0x0);
|
||||||
|
IoCsrWrite64 (LOONGARCH_IOCSR_MBUF3, 0x0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If mailbox 0 is non-NULL, it means that the BSP or other cores called the IPI to wake
|
||||||
|
// up the current core and let it use the resume vector stored in mailbox 0.
|
||||||
|
//
|
||||||
|
// If both the resume vector and parameter are non-NULL, it means that the IPI was
|
||||||
|
// called in the BIOS.
|
||||||
|
//
|
||||||
|
// The situation where the resume vector is non-NULL and the parameter is NULL has been
|
||||||
|
// processed after the exception entry is pushed onto the stack.
|
||||||
|
//
|
||||||
|
if ((ResumeVector != 0) && (Parameter != 0)) {
|
||||||
|
SystemContext.SystemContextLoongArch64->ERA = ResumeVector;
|
||||||
|
//
|
||||||
|
// Set $a0 as APIC ID and $a1 as parameter value.
|
||||||
|
//
|
||||||
|
SystemContext.SystemContextLoongArch64->R4 = CsrRead (LOONGARCH_CSR_CPUNUM);
|
||||||
|
SystemContext.SystemContextLoongArch64->R5 = Parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryFence ();
|
||||||
|
}
|
@ -0,0 +1,366 @@
|
|||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# LoongArch64 ASM exception handler
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/CpuLib.h>
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
|
||||||
|
#define RSIZE 8 // 64 bit mode register size
|
||||||
|
#define GP_REG_CONTEXT_SIZE 32 * RSIZE // General-purpose registers size
|
||||||
|
#define FP_REG_CONTEXT_SIZE 34 * RSIZE // Floating-point registers size
|
||||||
|
#define CSR_REG_CONTEXT_SIZE 9 * RSIZE // CSR registers size
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(ExceptionEntry)
|
||||||
|
ASM_GLOBAL ASM_PFX(ExceptionEntryStart)
|
||||||
|
ASM_GLOBAL ASM_PFX(ExceptionEntryEnd)
|
||||||
|
|
||||||
|
ASM_PFX(ExceptionEntry):
|
||||||
|
move $s0, $a0
|
||||||
|
bl GetExceptionType // Exception type stored in register a0
|
||||||
|
move $a1, $s0 // SystemContxt
|
||||||
|
bl CommonExceptionHandler
|
||||||
|
|
||||||
|
PopContext:
|
||||||
|
//
|
||||||
|
// Not sure if interrupts are turned on during the exception handler, anyway disable interrupts here.
|
||||||
|
// It will be turned on when the instruction 'ertn' is executed.
|
||||||
|
//
|
||||||
|
bl DisableInterrupts
|
||||||
|
|
||||||
|
bl GetExceptionType // Get current exception type, and stored in register a0
|
||||||
|
|
||||||
|
// Check whether the FPE is changed during interrupt handler, if ture restore it.
|
||||||
|
ld.d $t1, $sp, (LOONGARCH_CSR_EUEN * RSIZE + GP_REG_CONTEXT_SIZE)
|
||||||
|
csrrd $t0, LOONGARCH_CSR_EUEN // Current EUEN
|
||||||
|
andi $t0, $t0, CSR_EUEN_FPEN
|
||||||
|
andi $t1, $t1, CSR_EUEN_FPEN
|
||||||
|
li.d $t2, EXCEPT_LOONGARCH_INT
|
||||||
|
bne $a0, $t2, PopRegs
|
||||||
|
beq $t0, $t1, PopRegs
|
||||||
|
beqz $t1, CloseFP
|
||||||
|
bl EnableFloatingPointUnits
|
||||||
|
b PopRegs
|
||||||
|
|
||||||
|
CloseFP:
|
||||||
|
bl DisableFloatingPointUnits
|
||||||
|
|
||||||
|
PopRegs:
|
||||||
|
//
|
||||||
|
// Pop CSR reigsters
|
||||||
|
//
|
||||||
|
addi.d $sp, $sp, GP_REG_CONTEXT_SIZE
|
||||||
|
|
||||||
|
ld.d $t0, $sp, LOONGARCH_CSR_CRMD * RSIZE
|
||||||
|
csrwr $t0, LOONGARCH_CSR_CRMD
|
||||||
|
ld.d $t0, $sp, LOONGARCH_CSR_PRMD * RSIZE
|
||||||
|
csrwr $t0, LOONGARCH_CSR_PRMD
|
||||||
|
ld.d $t0, $sp, LOONGARCH_CSR_ECFG * RSIZE
|
||||||
|
csrwr $t0, LOONGARCH_CSR_ECFG
|
||||||
|
ld.d $t0, $sp, LOONGARCH_CSR_ERA * RSIZE
|
||||||
|
csrwr $t0, LOONGARCH_CSR_ERA
|
||||||
|
|
||||||
|
addi.d $sp, $sp, CSR_REG_CONTEXT_SIZE // Fource change the stack pointer befor pop the FP registers.
|
||||||
|
|
||||||
|
beqz $t1, PopGP // If the FPE not set, only pop the GP registers.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pop FP registers
|
||||||
|
//
|
||||||
|
fld.d $fa0, $sp, 0 * RSIZE
|
||||||
|
fld.d $fa1, $sp, 1 * RSIZE
|
||||||
|
fld.d $fa2, $sp, 2 * RSIZE
|
||||||
|
fld.d $fa3, $sp, 3 * RSIZE
|
||||||
|
fld.d $fa4, $sp, 4 * RSIZE
|
||||||
|
fld.d $fa5, $sp, 5 * RSIZE
|
||||||
|
fld.d $fa6, $sp, 6 * RSIZE
|
||||||
|
fld.d $fa7, $sp, 7 * RSIZE
|
||||||
|
fld.d $ft0, $sp, 8 * RSIZE
|
||||||
|
fld.d $ft1, $sp, 9 * RSIZE
|
||||||
|
fld.d $ft2, $sp, 10 * RSIZE
|
||||||
|
fld.d $ft3, $sp, 11 * RSIZE
|
||||||
|
fld.d $ft4, $sp, 12 * RSIZE
|
||||||
|
fld.d $ft5, $sp, 13 * RSIZE
|
||||||
|
fld.d $ft6, $sp, 14 * RSIZE
|
||||||
|
fld.d $ft7, $sp, 15 * RSIZE
|
||||||
|
fld.d $ft8, $sp, 16 * RSIZE
|
||||||
|
fld.d $ft9, $sp, 17 * RSIZE
|
||||||
|
fld.d $ft10, $sp, 18 * RSIZE
|
||||||
|
fld.d $ft11, $sp, 19 * RSIZE
|
||||||
|
fld.d $ft12, $sp, 20 * RSIZE
|
||||||
|
fld.d $ft13, $sp, 21 * RSIZE
|
||||||
|
fld.d $ft14, $sp, 22 * RSIZE
|
||||||
|
fld.d $ft15, $sp, 23 * RSIZE
|
||||||
|
fld.d $fs0, $sp, 24 * RSIZE
|
||||||
|
fld.d $fs1, $sp, 25 * RSIZE
|
||||||
|
fld.d $fs2, $sp, 26 * RSIZE
|
||||||
|
fld.d $fs3, $sp, 27 * RSIZE
|
||||||
|
fld.d $fs4, $sp, 28 * RSIZE
|
||||||
|
fld.d $fs5, $sp, 29 * RSIZE
|
||||||
|
fld.d $fs6, $sp, 30 * RSIZE
|
||||||
|
fld.d $fs7, $sp, 31 * RSIZE
|
||||||
|
|
||||||
|
ld.d $t0, $sp, 32 * RSIZE
|
||||||
|
movgr2fcsr $r0, $t0 // Pop the fcsr0 register.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pop the fcc0-fcc7 registers.
|
||||||
|
//
|
||||||
|
ld.d $t0, $sp, 33 * RSIZE
|
||||||
|
bstrpick.d $t1, $t0, 7, 0
|
||||||
|
movgr2cf $fcc0, $t1
|
||||||
|
bstrpick.d $t1, $t0, 15, 8
|
||||||
|
movgr2cf $fcc1, $t1
|
||||||
|
bstrpick.d $t1, $t0, 23, 16
|
||||||
|
movgr2cf $fcc2, $t1
|
||||||
|
bstrpick.d $t1, $t0, 31, 24
|
||||||
|
movgr2cf $fcc3, $t1
|
||||||
|
bstrpick.d $t1, $t0, 39, 32
|
||||||
|
movgr2cf $fcc4, $t1
|
||||||
|
bstrpick.d $t1, $t0, 47, 40
|
||||||
|
movgr2cf $fcc5, $t1
|
||||||
|
bstrpick.d $t1, $t0, 55, 48
|
||||||
|
movgr2cf $fcc6, $t1
|
||||||
|
bstrpick.d $t1, $t0, 63, 56
|
||||||
|
movgr2cf $fcc7, $t1
|
||||||
|
|
||||||
|
PopGP:
|
||||||
|
//
|
||||||
|
// Pop GP registers
|
||||||
|
//
|
||||||
|
addi.d $sp, $sp, -(GP_REG_CONTEXT_SIZE + CSR_REG_CONTEXT_SIZE)
|
||||||
|
ld.d $ra, $sp, 1 * RSIZE
|
||||||
|
ld.d $tp, $sp, 2 * RSIZE
|
||||||
|
ld.d $a0, $sp, 4 * RSIZE
|
||||||
|
ld.d $a1, $sp, 5 * RSIZE
|
||||||
|
ld.d $a2, $sp, 6 * RSIZE
|
||||||
|
ld.d $a3, $sp, 7 * RSIZE
|
||||||
|
ld.d $a4, $sp, 8 * RSIZE
|
||||||
|
ld.d $a5, $sp, 9 * RSIZE
|
||||||
|
ld.d $a6, $sp, 10 * RSIZE
|
||||||
|
ld.d $a7, $sp, 11 * RSIZE
|
||||||
|
ld.d $t0, $sp, 12 * RSIZE
|
||||||
|
ld.d $t1, $sp, 13 * RSIZE
|
||||||
|
ld.d $t2, $sp, 14 * RSIZE
|
||||||
|
ld.d $t3, $sp, 15 * RSIZE
|
||||||
|
ld.d $t4, $sp, 16 * RSIZE
|
||||||
|
ld.d $t5, $sp, 17 * RSIZE
|
||||||
|
ld.d $t6, $sp, 18 * RSIZE
|
||||||
|
ld.d $t7, $sp, 19 * RSIZE
|
||||||
|
ld.d $t8, $sp, 20 * RSIZE
|
||||||
|
ld.d $r21, $sp, 21 * RSIZE
|
||||||
|
ld.d $fp, $sp, 22 * RSIZE
|
||||||
|
ld.d $s0, $sp, 23 * RSIZE
|
||||||
|
ld.d $s1, $sp, 24 * RSIZE
|
||||||
|
ld.d $s2, $sp, 25 * RSIZE
|
||||||
|
ld.d $s3, $sp, 26 * RSIZE
|
||||||
|
ld.d $s4, $sp, 27 * RSIZE
|
||||||
|
ld.d $s5, $sp, 28 * RSIZE
|
||||||
|
ld.d $s6, $sp, 29 * RSIZE
|
||||||
|
ld.d $s7, $sp, 30 * RSIZE
|
||||||
|
ld.d $s8, $sp, 31 * RSIZE
|
||||||
|
ld.d $sp, $sp, 3 * RSIZE
|
||||||
|
|
||||||
|
ertn // Returen from exception.
|
||||||
|
//
|
||||||
|
// End of ExceptionEntry
|
||||||
|
//
|
||||||
|
|
||||||
|
ASM_PFX(ExceptionEntryStart):
|
||||||
|
//
|
||||||
|
// Store the old stack pointer in preparation for pushing the exception context onto the new stack.
|
||||||
|
//
|
||||||
|
csrwr $sp, LOONGARCH_CSR_KS0
|
||||||
|
|
||||||
|
csrrd $sp, LOONGARCH_CSR_KS0
|
||||||
|
|
||||||
|
//
|
||||||
|
// Push GP registers
|
||||||
|
//
|
||||||
|
addi.d $sp, $sp, -(GP_REG_CONTEXT_SIZE + FP_REG_CONTEXT_SIZE + CSR_REG_CONTEXT_SIZE)
|
||||||
|
st.d $zero, $sp, 0 * RSIZE
|
||||||
|
st.d $ra, $sp, 1 * RSIZE
|
||||||
|
st.d $tp, $sp, 2 * RSIZE
|
||||||
|
st.d $a0, $sp, 4 * RSIZE
|
||||||
|
st.d $a1, $sp, 5 * RSIZE
|
||||||
|
st.d $a2, $sp, 6 * RSIZE
|
||||||
|
st.d $a3, $sp, 7 * RSIZE
|
||||||
|
st.d $a4, $sp, 8 * RSIZE
|
||||||
|
st.d $a5, $sp, 9 * RSIZE
|
||||||
|
st.d $a6, $sp, 10 * RSIZE
|
||||||
|
st.d $a7, $sp, 11 * RSIZE
|
||||||
|
st.d $t0, $sp, 12 * RSIZE
|
||||||
|
st.d $t1, $sp, 13 * RSIZE
|
||||||
|
st.d $t2, $sp, 14 * RSIZE
|
||||||
|
st.d $t3, $sp, 15 * RSIZE
|
||||||
|
st.d $t4, $sp, 16 * RSIZE
|
||||||
|
st.d $t5, $sp, 17 * RSIZE
|
||||||
|
st.d $t6, $sp, 18 * RSIZE
|
||||||
|
st.d $t7, $sp, 19 * RSIZE
|
||||||
|
st.d $t8, $sp, 20 * RSIZE
|
||||||
|
st.d $r21, $sp, 21 * RSIZE
|
||||||
|
st.d $fp, $sp, 22 * RSIZE
|
||||||
|
st.d $s0, $sp, 23 * RSIZE
|
||||||
|
st.d $s1, $sp, 24 * RSIZE
|
||||||
|
st.d $s2, $sp, 25 * RSIZE
|
||||||
|
st.d $s3, $sp, 26 * RSIZE
|
||||||
|
st.d $s4, $sp, 27 * RSIZE
|
||||||
|
st.d $s5, $sp, 28 * RSIZE
|
||||||
|
st.d $s6, $sp, 29 * RSIZE
|
||||||
|
st.d $s7, $sp, 30 * RSIZE
|
||||||
|
st.d $s8, $sp, 31 * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_KS0 // Read the old stack pointer.
|
||||||
|
st.d $t0, $sp, 3 * RSIZE
|
||||||
|
|
||||||
|
//
|
||||||
|
// Push CSR registers
|
||||||
|
//
|
||||||
|
addi.d $sp, $sp, GP_REG_CONTEXT_SIZE
|
||||||
|
|
||||||
|
csrrd $t0, LOONGARCH_CSR_CRMD
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_CRMD * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_PRMD
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_PRMD * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_EUEN
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_EUEN * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_MISC
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_MISC * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_ECFG
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_ECFG * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_ESTAT
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_ESTAT * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_ERA
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_ERA * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_BADV
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_BADV * RSIZE
|
||||||
|
csrrd $t0, LOONGARCH_CSR_BADI
|
||||||
|
st.d $t0, $sp, LOONGARCH_CSR_BADI * RSIZE
|
||||||
|
|
||||||
|
//
|
||||||
|
// Push FP registers
|
||||||
|
//
|
||||||
|
addi.d $sp, $sp, CSR_REG_CONTEXT_SIZE
|
||||||
|
|
||||||
|
csrrd $t0, LOONGARCH_CSR_EUEN
|
||||||
|
andi $t0, $t0, CSR_EUEN_FPEN
|
||||||
|
beqz $t0, PushRegDone
|
||||||
|
|
||||||
|
fst.d $fa0, $sp, 0 * RSIZE
|
||||||
|
fst.d $fa1, $sp, 1 * RSIZE
|
||||||
|
fst.d $fa2, $sp, 2 * RSIZE
|
||||||
|
fst.d $fa3, $sp, 3 * RSIZE
|
||||||
|
fst.d $fa4, $sp, 4 * RSIZE
|
||||||
|
fst.d $fa5, $sp, 5 * RSIZE
|
||||||
|
fst.d $fa6, $sp, 6 * RSIZE
|
||||||
|
fst.d $fa7, $sp, 7 * RSIZE
|
||||||
|
fst.d $ft0, $sp, 8 * RSIZE
|
||||||
|
fst.d $ft1, $sp, 9 * RSIZE
|
||||||
|
fst.d $ft2, $sp, 10 * RSIZE
|
||||||
|
fst.d $ft3, $sp, 11 * RSIZE
|
||||||
|
fst.d $ft4, $sp, 12 * RSIZE
|
||||||
|
fst.d $ft5, $sp, 13 * RSIZE
|
||||||
|
fst.d $ft6, $sp, 14 * RSIZE
|
||||||
|
fst.d $ft7, $sp, 15 * RSIZE
|
||||||
|
fst.d $ft8, $sp, 16 * RSIZE
|
||||||
|
fst.d $ft9, $sp, 17 * RSIZE
|
||||||
|
fst.d $ft10, $sp, 18 * RSIZE
|
||||||
|
fst.d $ft11, $sp, 19 * RSIZE
|
||||||
|
fst.d $ft12, $sp, 20 * RSIZE
|
||||||
|
fst.d $ft13, $sp, 21 * RSIZE
|
||||||
|
fst.d $ft14, $sp, 22 * RSIZE
|
||||||
|
fst.d $ft15, $sp, 23 * RSIZE
|
||||||
|
fst.d $fs0, $sp, 24 * RSIZE
|
||||||
|
fst.d $fs1, $sp, 25 * RSIZE
|
||||||
|
fst.d $fs2, $sp, 26 * RSIZE
|
||||||
|
fst.d $fs3, $sp, 27 * RSIZE
|
||||||
|
fst.d $fs4, $sp, 28 * RSIZE
|
||||||
|
fst.d $fs5, $sp, 29 * RSIZE
|
||||||
|
fst.d $fs6, $sp, 30 * RSIZE
|
||||||
|
fst.d $fs7, $sp, 31 * RSIZE
|
||||||
|
|
||||||
|
movfcsr2gr $t3, $r0
|
||||||
|
st.d $t3, $sp, 32 * RSIZE // Push the FCSR0 register.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Push the fcc0-fcc7 registers.
|
||||||
|
//
|
||||||
|
movcf2gr $t3, $fcc0
|
||||||
|
or $t2, $t3, $zero
|
||||||
|
movcf2gr $t3, $fcc1
|
||||||
|
bstrins.d $t2, $t3, 0xf, 0x8
|
||||||
|
movcf2gr $t3, $fcc2
|
||||||
|
bstrins.d $t2, $t3, 0x17, 0x10
|
||||||
|
movcf2gr $t3, $fcc3
|
||||||
|
bstrins.d $t2, $t3, 0x1f, 0x18
|
||||||
|
movcf2gr $t3, $fcc4
|
||||||
|
bstrins.d $t2, $t3, 0x27, 0x20
|
||||||
|
movcf2gr $t3, $fcc5
|
||||||
|
bstrins.d $t2, $t3, 0x2f, 0x28
|
||||||
|
movcf2gr $t3, $fcc6
|
||||||
|
bstrins.d $t2, $t3, 0x37, 0x30
|
||||||
|
movcf2gr $t3, $fcc7
|
||||||
|
bstrins.d $t2, $t3, 0x3f, 0x38
|
||||||
|
st.d $t2, $sp, 33 * RSIZE
|
||||||
|
//
|
||||||
|
// Push exception context down
|
||||||
|
//
|
||||||
|
|
||||||
|
PushRegDone:
|
||||||
|
//
|
||||||
|
// Process IPI only when mailbox3 is NULL and mailbox0 is no-NULL.
|
||||||
|
//
|
||||||
|
li.d $t0, LOONGARCH_IOCSR_MBUF0
|
||||||
|
iocsrrd.d $a0, $t0
|
||||||
|
beqz $a0, EntryConmmonHanlder
|
||||||
|
|
||||||
|
li.d $t0, LOONGARCH_IOCSR_MBUF3
|
||||||
|
iocsrrd.d $t1, $t0
|
||||||
|
bnez $t1, EntryConmmonHanlder
|
||||||
|
|
||||||
|
csrrd $t0, LOONGARCH_CSR_ESTAT
|
||||||
|
srli.d $t0, $t0, 12
|
||||||
|
andi $t0, $t0, 0x1
|
||||||
|
beqz $t0, EntryConmmonHanlder
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean up current processor mailbox 0 and mailbox 3.
|
||||||
|
//
|
||||||
|
li.d $t0, LOONGARCH_IOCSR_MBUF0
|
||||||
|
iocsrwr.d $zero, $t0
|
||||||
|
li.d $t0, LOONGARCH_IOCSR_MBUF3
|
||||||
|
iocsrwr.d $zero, $t0
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear IPI interrupt.
|
||||||
|
//
|
||||||
|
li.d $t0, LOONGARCH_IOCSR_IPI_STATUS
|
||||||
|
iocsrrd.w $t1, $t0
|
||||||
|
li.d $t0, LOONGARCH_IOCSR_IPI_CLEAR
|
||||||
|
iocsrwr.w $t1, $t0
|
||||||
|
|
||||||
|
//
|
||||||
|
// Only kernel stage BSP calls IPI without parameters. Clean up the PIE and make sure
|
||||||
|
// global interrupts are turned off for the current processor when jumping to the kernel.
|
||||||
|
//
|
||||||
|
csrwr $a0, LOONGARCH_CSR_ERA // Update ERA
|
||||||
|
li.w $t0, BIT2 // IE
|
||||||
|
csrxchg $zero, $t0, LOONGARCH_CSR_PRMD // Clean PIE
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return this exception and jump to kernel using ERA.
|
||||||
|
//
|
||||||
|
ertn
|
||||||
|
|
||||||
|
EntryConmmonHanlder:
|
||||||
|
addi.d $sp, $sp, -(GP_REG_CONTEXT_SIZE + CSR_REG_CONTEXT_SIZE)
|
||||||
|
move $a0, $sp
|
||||||
|
la.abs $ra, ExceptionEntry
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
ASM_PFX(ExceptionEntryEnd):
|
||||||
|
.end
|
@ -0,0 +1,102 @@
|
|||||||
|
/** @file SecPeiExceptionLib.c
|
||||||
|
|
||||||
|
LoongArch exception library implemenation for PEI and SEC modules.
|
||||||
|
|
||||||
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/CpuLib.h>
|
||||||
|
#include <Library/CpuExceptionHandlerLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/SerialPortLib.h>
|
||||||
|
#include <Protocol/DebugSupport.h>
|
||||||
|
#include <Register/LoongArch64/Csr.h>
|
||||||
|
|
||||||
|
#include "ExceptionCommon.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Registers a function to be called from the processor interrupt or exception handler.
|
||||||
|
|
||||||
|
Always return EFI_UNSUPPORTED in the SEC exception initialization module.
|
||||||
|
|
||||||
|
@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_UNSUPPORTED The interrupt specified by InterruptType is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
RegisterCpuInterruptHandler (
|
||||||
|
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||||
|
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Common exception handler.
|
||||||
|
|
||||||
|
@param ExceptionType Exception type.
|
||||||
|
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
CommonExceptionHandler (
|
||||||
|
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||||
|
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_EXCEPTION_TYPE InterruptType;
|
||||||
|
|
||||||
|
if (ExceptionType == EXCEPT_LOONGARCH_INT) {
|
||||||
|
//
|
||||||
|
// Interrupt
|
||||||
|
//
|
||||||
|
InterruptType = GetInterruptType (SystemContext);
|
||||||
|
if (InterruptType == EXCEPT_LOONGARCH_INT_IPI) {
|
||||||
|
//
|
||||||
|
// APs may wake up via IPI IRQ during the SEC or PEI phase, clear the IPI interrupt and
|
||||||
|
// perform the remaining work.
|
||||||
|
//
|
||||||
|
IpiInterruptHandler (InterruptType, SystemContext);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
ExceptionType = InterruptType;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Exception
|
||||||
|
//
|
||||||
|
ExceptionType >>= CSR_ESTAT_EXC_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultExceptionHandler (ExceptionType, SystemContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes all CPU exceptions entries and provides the default exception handlers.
|
||||||
|
|
||||||
|
Always return EFI_SUCCESS in the SEC exception initialization module.
|
||||||
|
|
||||||
|
@param[in] VectorInfo Pointer to reserved vector list.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
|
||||||
|
with default exception handlers.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
InitializeCpuExceptionHandlers (
|
||||||
|
IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
# CPU Exception Handler library instance for SEC/PEI modules.
|
# CPU Exception Handler library instance for SEC/PEI modules.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@ -19,6 +20,7 @@
|
|||||||
# The following information is for reference only and not required by the build tools.
|
# The following information is for reference only and not required by the build tools.
|
||||||
#
|
#
|
||||||
# VALID_ARCHITECTURES = IA32 X64
|
# VALID_ARCHITECTURES = IA32 X64
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64 LOONGARCH64
|
||||||
#
|
#
|
||||||
|
|
||||||
[Sources.Ia32]
|
[Sources.Ia32]
|
||||||
@ -32,24 +34,37 @@
|
|||||||
X64/ArchInterruptDefs.h
|
X64/ArchInterruptDefs.h
|
||||||
X64/SecPeiExceptionHandlerAsm.nasm
|
X64/SecPeiExceptionHandlerAsm.nasm
|
||||||
|
|
||||||
[Sources.common]
|
[Sources.Ia32, Sources.X64]
|
||||||
CpuExceptionCommon.h
|
CpuExceptionCommon.h
|
||||||
CpuExceptionCommon.c
|
CpuExceptionCommon.c
|
||||||
SecPeiCpuException.c
|
SecPeiCpuException.c
|
||||||
|
|
||||||
|
[Sources.LoongArch64]
|
||||||
|
LoongArch/ExceptionCommon.h
|
||||||
|
LoongArch/ExceptionCommon.c
|
||||||
|
LoongArch/SecPeiExceptionLib.c
|
||||||
|
LoongArch/LoongArch64/ArchExceptionHandler.c
|
||||||
|
LoongArch/LoongArch64/ExceptionHandlerAsm.S | GCC
|
||||||
|
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
MdeModulePkg/MdeModulePkg.dec
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
UefiCpuPkg/UefiCpuPkg.dec
|
UefiCpuPkg/UefiCpuPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses.common]
|
||||||
BaseLib
|
BaseLib
|
||||||
CcExitLib
|
|
||||||
LocalApicLib
|
|
||||||
PeCoffGetEntryPointLib
|
PeCoffGetEntryPointLib
|
||||||
PrintLib
|
PrintLib
|
||||||
SerialPortLib
|
SerialPortLib
|
||||||
|
|
||||||
|
[LibraryClasses.Ia32, LibraryClasses.X64]
|
||||||
|
CcExitLib
|
||||||
|
LocalApicLib
|
||||||
|
|
||||||
|
[LibraryClasses.LoongArch64]
|
||||||
|
CpuLib
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
|
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
|
||||||
|
Loading…
x
Reference in New Issue
Block a user