From nobody Sat Feb 7 05:56:27 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+112954+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+112954+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1703757954; cv=none; d=zohomail.com; s=zohoarc; b=mzcdSbOXIk5SwSnXz2bNlD2e261eiqkIjIsUk6m1A0nkomwmiJ4ZQ/91Dhr7aW+WJhymv9oezqRzlpzNS8y7+wXVvmT8zxSNRprOCR4PtVqjq9cmMh9RJd6DA2fgJomEu3xtfXl/iqdzRklscIlDlr95ImUTC/VZdB81gmVo3Ss= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1703757954; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=anm9g6tPpdIggRjc9AIqkTg+DQMBgyXZ2FiWesul3GI=; b=EU2hb28kMNOab9bcRiVH5zJRLqC0VKFvVsdi9qpc6vSODAzEgUTe1uci2V3KUOUMLc7zHAfwiqa/Zc+P+J5Z23tXs1wKlDAkHaOBHW9UIBbWHWRJN/9aHr/5DRp5bCZRxsMOhjJkJM2X7K7/jcGTX1odVLomgnd0Q2mONXDdR/g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+112954+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1703757954340642.464555231952; Thu, 28 Dec 2023 02:05:54 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=zbOt9r7Hw3+tGTu5I6LGmdXX0zPVBrITA/s5+DSC+NY=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1703757953; v=1; b=Mftgy6zk/F1wDs+1NMQ12wsBGGBpwyOJAMa1lIWpT3MryJqaLwsKPTWqggL2BmsDmhTk/1xb RbdFCQSbuSxG0oSAEL+AQOCm8mrQ4Igf/qeOX680f37akdXJkF6bKkdQeN557YiLqQUsdy+Rua2 uDlRTCJqyWzp1BORXqeQafSY= X-Received: by 127.0.0.2 with SMTP id tZhBYY1788612xiAXO2F2Xfa; Thu, 28 Dec 2023 02:05:53 -0800 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.120610.1703757952772563753 for ; Thu, 28 Dec 2023 02:05:53 -0800 X-Received: from loongson.cn (unknown [10.2.9.245]) by gateway (Coremail) with SMTP id _____8AxnvB+SI1l5AIAAA--.100S3; Thu, 28 Dec 2023 18:05:50 +0800 (CST) X-Received: from code-server.gen (unknown [10.2.9.245]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Axeb18SI1lowQOAA--.19855S2; Thu, 28 Dec 2023 18:05:48 +0800 (CST) From: "Chao Li" To: devel@edk2.groups.io Cc: Eric Dong , Ray Ni , Rahul Kumar , Gerd Hoffmann , Michael D Kinney , Liming Gao , Zhiguang Liu , Baoqi Zhang Subject: [edk2-devel] [PATCH v5 11/36] UefiCpuPkg: Add CPU exception library for LoongArch Date: Thu, 28 Dec 2023 18:05:47 +0800 Message-Id: <20231228100547.1765262-1-lichao@loongson.cn> In-Reply-To: <20231228100351.1756165-1-lichao@loongson.cn> References: <20231228100351.1756165-1-lichao@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Axeb18SI1lowQOAA--.19855S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQATCGWM2y8KPQATsj X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lichao@loongson.cn List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: GtDlilB2oyXGWw1LSEPPYonEx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1703757955758100003 Content-Type: text/plain; charset="utf-8" Added a new library named LoongArch64CpuExceptionHandlerLib, and modified the way LoongArch exceptions are expressed. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4584 Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Signed-off-by: Chao Li Co-authored-by: Baoqi Zhang Acked-by: Ray Ni --- MdePkg/Include/Protocol/DebugSupport.h | 14 + .../DxeCpuExceptionHandlerLib.inf | 45 +++ .../DxeCpuExceptionHandlerLib.uni | 15 + .../DxeExceptionLib.c | 198 +++++++++++ .../ExceptionCommon.c | 170 ++++++++++ .../ExceptionCommon.h | 118 +++++++ .../LoongArch64/ArchExceptionHandler.c | 213 ++++++++++++ .../LoongArch64/ExceptionHandlerAsm.S | 320 ++++++++++++++++++ .../SecPeiCpuExceptionHandlerLib.inf | 45 +++ .../SecPeiCpuExceptionHandlerLib.uni | 15 + .../SecPeiExceptionLib.c | 88 +++++ UefiCpuPkg/UefiCpuPkg.dec | 6 + UefiCpuPkg/UefiCpuPkg.dsc | 2 + 13 files changed, 1249 insertions(+) create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Dx= eCpuExceptionHandlerLib.inf create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Dx= eCpuExceptionHandlerLib.uni create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Dx= eExceptionLib.c create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Ex= ceptionCommon.c create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Ex= ceptionCommon.h create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Lo= ongArch64/ArchExceptionHandler.c create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Lo= ongArch64/ExceptionHandlerAsm.S create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Se= cPeiCpuExceptionHandlerLib.inf create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Se= cPeiCpuExceptionHandlerLib.uni create mode 100644 UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Se= cPeiExceptionLib.c diff --git a/MdePkg/Include/Protocol/DebugSupport.h b/MdePkg/Include/Protoc= ol/DebugSupport.h index 9742663619..06f99ba7f7 100644 --- a/MdePkg/Include/Protocol/DebugSupport.h +++ b/MdePkg/Include/Protocol/DebugSupport.h @@ -683,6 +683,20 @@ typedef struct { // // LoongArch processor exception types. // +// The exception types is located in the CSR ESTAT +// register offset 16 bits, width 6 bits. +// +// If you want to register an exception hook, you can +// shfit the number left by 16 bits, and the exception +// handler will know the types. +// +// For example: +// mCpu->CpuRegisterInterruptHandler ( +// mCpu, +// (EXCEPT_LOONGARCH_PPI << CSR_ESTAT_EXC_SHIFT), +// PpiExceptionHandler +// ); +// #define EXCEPT_LOONGARCH_INT 0 #define EXCEPT_LOONGARCH_PIL 1 #define EXCEPT_LOONGARCH_PIS 2 diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/DxeCpuExc= eptionHandlerLib.inf b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib= /DxeCpuExceptionHandlerLib.inf new file mode 100644 index 0000000000..0ce8abe98d --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/DxeCpuExceptionH= andlerLib.inf @@ -0,0 +1,45 @@ +## @file +# LoongArch exception library instance for DXE modules. +# +# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights= reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 1.29 + BASE_NAME =3D DxeCpuExceptionHandlerLib + MODULE_UNI_FILE =3D DxeCpuExceptionHandlerLib.uni + FILE_GUID =3D 23C5D29F-F54B-091B-BD94-027576ED09FA + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D CpuExceptionHandlerLib|DXE_CORE DXE_D= RIVER UEFI_APPLICATION + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources.LoongArch64] + LoongArch64/ArchExceptionHandler.c + LoongArch64/ExceptionHandlerAsm.S | GCC + +[Sources] + DxeExceptionLib.c + ExceptionCommon.h + ExceptionCommon.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + CpuLib + PeCoffGetEntryPointLib + PrintLib + SerialPortLib + SynchronizationLib diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/DxeCpuExc= eptionHandlerLib.uni b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib= /DxeCpuExceptionHandlerLib.uni new file mode 100644 index 0000000000..25b1593666 --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/DxeCpuExceptionH= andlerLib.uni @@ -0,0 +1,15 @@ +// /** @file +// CPU Exception Handler library instance for DXE modules. +// +// CPU Exception Handler library instance for DXE modules. +// +// Copyright (c) 2024, Loongson Technology Corporation Limited. All rights= reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Exception Han= dler library instance for DXE modules." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Exception Han= dler library instance for DXE modules." diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/DxeExcept= ionLib.c b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/DxeExceptio= nLib.c new file mode 100644 index 0000000000..2c5d202b33 --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/DxeExceptionLib.c @@ -0,0 +1,198 @@ +/** @file DxeExceptionLib.c + + LoongArch exception library implemenation for DXE modules. + + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights = reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ExceptionCommon.h" + +EFI_EXCEPTION_CALLBACK ExternalInterruptHandler[MAX_LOONGARCH_INTERRUPT += 1] =3D { 0 }; +EFI_EXCEPTION_CALLBACK ExceptionHandler[MAX_LOONGARCH_EXCEPTION + 1] = =3D { 0 }; + +/** + Registers a function to be called from the processor interrupt or except= ion handler. + + This function registers and enables the handler specified by InterruptHa= ndler for a processor + interrupt or exception type specified by InterruptType. If InterruptHand= ler is NULL, then the + handler for the processor interrupt or exception type specified by Inter= ruptType is uninstalled. + The installed handler is called once for each processor interrupt or exc= eption. + + @param InterruptType A pointer to the processor's current interrupt = state. Set to TRUE if interrupts + are enabled and FALSE if interrupts are disable= d. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRU= PT_HANDLER that is called + when a processor interrupt occurs. If this para= meter is NULL, then the handler + will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt wa= s successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handle= r for InterruptType was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler fo= r InterruptType was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType i= s not supported. + +**/ +EFI_STATUS +RegisterCpuInterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ) +{ + EFI_EXCEPTION_TYPE ExceptionType; + + ExceptionType =3D InterruptType & CSR_ESTAT_EXC; + + if (ExceptionType !=3D 0) { + // + // Exception + // + if (ExceptionType > EXCEPT_LOONGARCH_FPE) { + return EFI_UNSUPPORTED; + } + + ExceptionType >>=3D CSR_ESTAT_EXC_SHIFT; + + if ((InterruptHandler =3D=3D NULL) && (ExceptionHandler[InterruptType]= =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((InterruptHandler !=3D NULL) && (ExceptionHandler[ExceptionType] != =3D NULL)) { + return EFI_ALREADY_STARTED; + } + + ExceptionHandler[ExceptionType] =3D InterruptHandler; + } else { + // + // Interrupt + // + if (InterruptType > MAX_LOONGARCH_INTERRUPT) { + return EFI_UNSUPPORTED; + } + + if ((InterruptHandler =3D=3D NULL) && (ExternalInterruptHandler[Interr= uptType] =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((InterruptHandler !=3D NULL) && (ExternalInterruptHandler[Interrup= tType] !=3D NULL)) { + return EFI_ALREADY_STARTED; + } + + ExternalInterruptHandler[InterruptType] =3D 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 =3D=3D EXCEPT_LOONGARCH_INT) { + // + // Interrupt + // + InterruptType =3D GetInterruptType (SystemContext); + if (InterruptType =3D=3D 0xFF) { + ExceptionType =3D InterruptType; + } else { + if ((ExternalInterruptHandler !=3D NULL) && (ExternalInterruptHandle= r[InterruptType] !=3D NULL)) { + ExternalInterruptHandler[InterruptType](InterruptType, SystemConte= xt); + return; + } + } + } else if (ExceptionType =3D=3D EXCEPT_LOONGARCH_FPD) { + EnableFloatingPointUnits (); + InitializeFloatingPointUnits (); + return; + } else { + // + // Exception + // + ExceptionType >>=3D CSR_ESTAT_EXC_SHIFT; + if ((ExceptionHandler !=3D NULL) && (ExceptionHandler[ExceptionType] != =3D NULL)) { + ExceptionHandler[ExceptionType](ExceptionType, SystemContext); + return; + } + } + + // + // Only the TLB refill exception use the same entry point as normal exce= ptions. + // + if (CsrRead (LOONGARCH_CSR_TLBRERA) & 0x1) { + ExceptionType =3D mExceptionKnownNameNum - 1; // Use only to dump the = exception context. + } + + DefaultExceptionHandler (ExceptionType, SystemContext); +} + +/** + Initializes all CPU exceptions entries and provides the default exceptio= n 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 Vec= torInfo 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 successful= ly 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 exceptio= n stack. + @param[in, out] BufferSize On input, it indicates the byte size of B= uffer. + If the size is not enough, the return sta= tus will + be EFI_BUFFER_TOO_SMALL, and output Buffe= rSize + 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; +} diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Exception= Common.c b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/ExceptionCo= mmon.c new file mode 100644 index 0000000000..0df904674c --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/ExceptionCommon.c @@ -0,0 +1,170 @@ +/** @file DxeExceptionLib.c + + CPU Exception Handler Library common functions. + + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights = reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include "ExceptionCommon.h" + +CONST CHAR8 mExceptionReservedStr[] =3D "Reserved"; +CONST CHAR8 *mExceptionNameStr[] =3D { + "#INT - Interrupt(CSR.ECFG.VS=3D0)", + "#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 instructi= on disable exception", + "#FPE - Floating-Point error exception", + "#WPE - WatchPoint Exception for Fetch watchpoint or Memory load/store w= atchpoint", + "#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 exce= ption is not instructed in ECODE, so the TLB refill exception must be the l= ast one! +}; + +INTN mExceptionKnownNameNum =3D (sizeof (mExceptionNameStr) / sizeof (CHA= R8 *)); + +/** + 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 =3D PeCoffSearchImageBase (CurrentEra); + if (Pe32Data =3D=3D 0) { + InternalPrintMessage ("!!!! Can't find image information. !!!!\n"); + } else { + // + // Find Image Base entry point + // + Status =3D PeCoffLoaderGetEntryPoint ((VOID *)Pe32Data, &EntryPoint); + if (EFI_ERROR (Status)) { + EntryPoint =3D NULL; + } + + InternalPrintMessage ("!!!! Find image based on IP(0x%x) ", CurrentEra= ); + PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data); + if (PdbPointer !=3D NULL) { + InternalPrintMessage ("%a", PdbPointer); + } else { + InternalPrintMessage ("(No PDB) "); + } + + InternalPrintMessage ( + " (ImageBase=3D%016lp, EntryPoint=3D%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 (); +} diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/Exception= Common.h b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/ExceptionCo= mmon.h new file mode 100644 index 0000000000..8b626032c7 --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/ExceptionCommon.h @@ -0,0 +1,118 @@ +/** @file DxeExceptionLib.h + + Common header file for CPU Exception Handler Library. + + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights = reserved.
+ + 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 access= ed + 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 + ); + +/** + 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 diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/LoongArch= 64/ArchExceptionHandler.c b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandl= erLib/LoongArch64/ArchExceptionHandler.c new file mode 100644 index 0000000000..04e6d17c45 --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/LoongArch64/Arch= ExceptionHandler.c @@ -0,0 +1,213 @@ +/** @file ArchExceptionHandler.c + + LoongArch64 CPU Exception Handler. + + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights = reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#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 =3D (SystemContext.SystemContextLoongArch64->ESTAT & CSR_E= STAT_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 =3D 0; InterruptType <=3D EXCEPT_LOONGARCH_INT_IPI; I= nterruptType++) { + if (SystemContext.SystemContextLoongArch64->ESTAT & (1 << InterruptTyp= e)) { + // + // 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 =3D=3D (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 =3D=3D (mExceptionKnownNameNum - 1)) { + // + // Dump TLB refill image info + // + DumpModuleImageInfo ((CsrRead (LOONGARCH_CSR_TLBRERA) & (~0x3ULL))); + } else { + DumpModuleImageInfo (SystemContext.SystemContextLoongArch64->ERA); + } +} diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/LoongArch= 64/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandle= rLib/LoongArch64/ExceptionHandlerAsm.S new file mode 100644 index 0000000000..15d84baa77 --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/LoongArch64/Exce= ptionHandlerAsm.S @@ -0,0 +1,320 @@ +#-------------------------------------------------------------------------= ----- +# +# LoongArch64 ASM exception handler +# +# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#-------------------------------------------------------------------------= ----- + +#include +#include +#include + +#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, an= yway disable interrupts here. + // It will be turned on when the instruction 'ertn' is executed. + // + bl DisableInterrupts + + bl GetExceptionType // Get current exception type, and store= d in register a0 + + // Check whether the FPE is changed during interrupt handler, if ture re= store 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 point= er 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: + 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 diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/SecPeiCpu= ExceptionHandlerLib.inf b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandler= Lib/SecPeiCpuExceptionHandlerLib.inf new file mode 100644 index 0000000000..437c92e26d --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/SecPeiCpuExcepti= onHandlerLib.inf @@ -0,0 +1,45 @@ +## @file +# LoongArch exception library instance for PEI and SEC modules. +# +# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights= reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 1.29 + BASE_NAME =3D SecPeiCpuExceptionHandlerLib + MODULE_UNI_FILE =3D SecPeiCpuExceptionHandlerLib.uni + FILE_GUID =3D 0D69E6CD-1423-F118-C4EF-7AA439BC3E3B + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D CpuExceptionHandlerLib|SEC PEI_CORE P= EIM + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources.LoongArch64] + LoongArch64/ArchExceptionHandler.c + LoongArch64/ExceptionHandlerAsm.S | GCC + +[Sources] + ExceptionCommon.h + ExceptionCommon.c + SecPeiExceptionLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + CpuLib + PeCoffGetEntryPointLib + PrintLib + SerialPortLib + SynchronizationLib diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/SecPeiCpu= ExceptionHandlerLib.uni b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandler= Lib/SecPeiCpuExceptionHandlerLib.uni new file mode 100644 index 0000000000..591cddc87b --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/SecPeiCpuExcepti= onHandlerLib.uni @@ -0,0 +1,15 @@ +// /** @file +// CPU Exception Handler library instance for SEC/PEI modules. +// +// CPU Exception Handler library instance for SEC/PEI modules. +// +// Copyright (c) 2024, Loongson Technology Corporation Limited. All rights= reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Exception Han= dler library instance for SEC/PEI modules." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Exception Han= dler library instance for SEC/PEI modules." diff --git a/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/SecPeiExc= eptionLib.c b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/SecPeiEx= ceptionLib.c new file mode 100644 index 0000000000..c514598fb0 --- /dev/null +++ b/UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/SecPeiExceptionL= ib.c @@ -0,0 +1,88 @@ +/** @file SecPeiExceptionLib.c + + LoongArch exception library implemenation for PEI and SEC modules. + + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights = reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include "ExceptionCommon.h" + +/** + Registers a function to be called from the processor interrupt or except= ion 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 disable= d. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRU= PT_HANDLER that is called + when a processor interrupt occurs. If this para= meter 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 + ) +{ + // + // APs may wake up by IPI IRQ during the SEC or PEI phase, clear the IPI= interrupt and return. + // + if (GetInterruptType (SystemContext) =3D=3D EXCEPT_LOONGARCH_INT_IPI) { + DisableLocalInterrupts (1 << EXCEPT_LOONGARCH_INT_IPI); + IoCsrWrite32 (LOONGARCH_IOCSR_IPI_CLEAR, IoCsrRead32 (LOONGARCH_IOCSR_= IPI_STATUS)); + return; + } else { + ExceptionType >>=3D CSR_ESTAT_EXC_SHIFT; + DefaultExceptionHandler (ExceptionType, SystemContext); + } +} + +/** + Initializes all CPU exceptions entries and provides the default exceptio= n 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 i= nitialized + with default exception handlers. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuExceptionHandlers ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL + ) +{ + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index cc785a3222..84f61254bb 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -3,6 +3,7 @@ # # Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.
# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights = reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -410,6 +411,11 @@ # 10 - 57bit mode. gUefiCpuPkgTokenSpaceGuid.PcdCpuRiscVMmuMaxSatpMode|10|UINT32|0x60000021 =20 +[PcdsFixedAtBuild.LoongArch64, PcdsPatchableInModule.LoongArch64, PcdsDyna= mic.LoongArch64, PcdsDynamicEx.LoongArch64] + ## Contains the pointer to a CPU exception vector base address. + # @Prompt The pointer to a CPU exception vector base address. + gUefiCpuPkgTokenSpaceGuid.PcdCpuExceptionVectorBaseAddress|0x0|UINT64|0x= 62640000 + [PcdsDynamic, PcdsDynamicEx] ## Contains the pointer to a CPU S3 data buffer of structure ACPI_CPU_DA= TA. # @Prompt The pointer to a CPU S3 data buffer. diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index a977884c3d..0b8ea858b2 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -209,6 +209,8 @@ =20 [Components.LOONGARCH64] UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib= .inf + UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/SecPeiCpuExceptionH= andlerLib.inf + UefiCpuPkg/Library/LoongArch64CpuExceptionHandlerLib/DxeCpuExceptionHand= lerLib.inf =20 [BuildOptions] *_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES --=20 2.27.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#112954): https://edk2.groups.io/g/devel/message/112954 Mute This Topic: https://groups.io/mt/103398605/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-