From: "Chao Li" <lichao@loongson.cn>
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>,
Jiewen Yao <jiewen.yao@intel.com>,
Jordan Justen <jordan.l.justen@intel.com>,
Gerd Hoffmann <kraxel@redhat.com>, Bibo Mao <maobibo@loongson.cn>,
Dongyan Qian <qiandongyan@loongson.cn>,
Xianglai Li <lixianglai@loongson.cn>
Subject: [edk2-devel] [PATCH v6 33/36] OvmfPkg/LoongArchVirt: Support SEC phase
Date: Fri, 5 Jan 2024 17:46:34 +0800 [thread overview]
Message-ID: <20240105094634.2282358-1-lichao@loongson.cn> (raw)
In-Reply-To: <20240105094118.2279380-1-lichao@loongson.cn>
Add SEC code for LoongArch virtual machine.
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Bibo Mao <maobibo@loongson.cn>
Cc: Dongyan Qian <qiandongyan@loongson.cn>
Signed-off-by: Chao Li <lichao@loongson.cn>
Co-authored-by: Xianglai Li <lixianglai@loongson.cn>
Co-authored-by: Bibo Mao <maobibo@loongson.cn>
---
OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S | 180 +++++++
OvmfPkg/LoongArchVirt/Sec/SecMain.c | 507 ++++++++++++++++++
OvmfPkg/LoongArchVirt/Sec/SecMain.inf | 53 ++
3 files changed, 740 insertions(+)
create mode 100644 OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S
create mode 100644 OvmfPkg/LoongArchVirt/Sec/SecMain.c
create mode 100644 OvmfPkg/LoongArchVirt/Sec/SecMain.inf
diff --git a/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S
new file mode 100644
index 0000000000..ed099ba0fc
--- /dev/null
+++ b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S
@@ -0,0 +1,180 @@
+#------------------------------------------------------------------------------
+#
+# Start for Loongson LoongArch processor
+#
+# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# @par Glossary:
+# - CSR - CPU Status Register
+# - EBASE - Exception Base Address
+#------------------------------------------------------------------------------
+#ifndef __ASSEMBLY__
+#define __ASSEMBLY__
+#endif
+
+#include <Library/BaseMemoryLib.h>
+#include <Register/LoongArch64/Csr.h>
+#include <Protocol/DebugSupport.h>
+
+#define BOOTCORE_ID 0
+//
+// 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
+
+ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ /* Disable interrupt */
+ li.d $t0, (1 << 2)
+ csrxchg $zero, $t0, LOONGARCH_CSR_CRMD
+
+ /* Read physical cpu number id */
+ bl GetApicId
+ li.d $t0, BOOTCORE_ID //0
+ bne $a0, $t0, SlaveMain
+
+ /* Set BSP stack */
+ li.d $t0, FixedPcdGet64(PcdOvmfSecPeiTempRamBase) + FixedPcdGet32(PcdOvmfSecPeiTempRamSize) # stack base
+ move $sp, $t0
+ addi.d $sp, $sp, -0x8
+
+ /* Load the exception vector base address */
+ li.d $s0, FixedPcdGet64(PcdCpuExceptionVectorBaseAddress)
+
+ /* Construct SEC and PEI step exception environment */
+ la.pcrel $a1, ExceptionEntryStart
+ la.pcrel $t0, ExceptionEntryEnd
+ sub.d $a2, $t0, $a1
+ li.w $t0, (MAX_LOONGARCH_EXCEPTION + MAX_LOONGARCH_INTERRUPT) * 512
+ bgeu $a2, $t0, DeadLoop
+ move $a0, $s0
+ bl CopyMem
+
+ /* Configure BSP reset ebase */
+ move $a0, $s0
+ bl SetExceptionBaseAddress
+
+CallEntry:
+ /* Call C function make sure parameter true */
+ li.d $a0, FixedPcdGet64(PcdOvmfFdBaseAddress) # FW base
+ addi.d $a1, $sp, 0x8
+ bl SecCoreStartupWithStack
+# End of _ModuleEntryPoint
+
+ASM_PFX(ClearMailBox):
+ /* Clear mailbox */
+ li.d $t1, LOONGARCH_IOCSR_MBUF3
+ iocsrwr.d $zero, $t1
+ li.d $t1, LOONGARCH_IOCSR_MBUF2
+ iocsrwr.d $zero, $t1
+ li.d $t1, LOONGARCH_IOCSR_MBUF1
+ iocsrwr.d $zero, $t1
+ li.d $t1, LOONGARCH_IOCSR_MBUF0
+ iocsrwr.d $zero, $t1
+ jirl $zero, $ra, 0
+# End of ClearMailBox
+
+ASM_PFX(EnableIPI):
+ /* Enable IPI interrupt */
+ li.d $t1, (1 << 12)
+ csrxchg $t1, $t1, LOONGARCH_CSR_ECFG
+
+ addi.d $t2, $zero, -1
+ li.d $t1, LOONGARCH_IOCSR_IPI_EN
+ iocsrwr.w $t2, $t1
+ jirl $zero, $ra, 0
+# End of EeableIPI
+
+#/**
+# Get APIC ID for every CPU.
+#
+# @param NULL
+# @return APICID
+#
+# UINTN
+# EFI_API
+# GetApicId (
+# VOID
+# )
+#**/
+ASM_PFX(GetApicId):
+ csrrd $a0, LOONGARCH_CSR_CPUNUM
+ andi $a0, $a0, 0x3ff
+ jirl $zero, $ra, 0
+# End of GetApicId
+
+ASM_PFX(ApInitStack):
+ li.d $t1, SIZE_1KB
+ csrrd $t0, LOONGARCH_CSR_TMID
+ mul.d $t1, $t0, $t1
+ li.d $t2, FixedPcdGet32(PcdCpuMaxLogicalProcessorNumber)
+ bgeu $t0, $t2, DeadLoop
+ li.d $t0, FixedPcdGet64(PcdOvmfSecPeiTempRamBase) + FixedPcdGet32(PcdOvmfSecPeiTempRamSize) - SIZE_64KB
+ sub.d $sp, $t0, $t1
+ addi.d $sp, $sp, -0x8
+ jirl $zero, $ra, 0
+# End of ApInitStack
+
+ASM_PFX(SlaveMain):
+ /* Set AP exception handle in flash */
+ la.pcrel $a0, ApException
+ bl SetExceptionBaseAddress
+
+ /* Clean up local mail box and open INT */
+ bl ClearMailBox
+ bl EnableIPI
+ bl EnableInterrupts
+
+WaitForWake:
+ /* Wait for wakeup */
+ bl CpuSleep
+ b WaitForWake
+# End of SlaveMain
+
+.align 12
+ASM_PFX(ApException):
+ csrrd $t0, LOONGARCH_CSR_ESTAT
+ srli.d $t0, $t0, 12
+ beqz $t0, DeadLoop
+
+ li.d $t0, LOONGARCH_IOCSR_IPI_STATUS
+ iocsrrd.w $t1, $t0
+ li.d $t0, LOONGARCH_IOCSR_IPI_CLEAR
+ iocsrwr.w $t1, $t0
+
+ /* Read mail buf and jump to specified entry */
+ li.d $t1, LOONGARCH_IOCSR_MBUF0
+ iocsrrd.d $t0, $t1
+ beqz $t0, OutOfException
+ csrwr $t0, LOONGARCH_CSR_ERA
+ li.d $t0, LOONGARCH_IOCSR_MBUF3
+ iocsrrd.d $a1, $t0
+ bl ClearMailBox
+ beqz $a1, NoParameterCall
+
+ //
+ // If the parameters are not NULL, then calling happened in FW ENV.
+ // Set the EBASE to be the same as BSP.
+ //
+ li.d $a0, FixedPcdGet64(PcdCpuExceptionVectorBaseAddress)
+ bl SetExceptionBaseAddress
+
+ bl ApInitStack
+ bl GetApicId
+ b OutOfException
+NoParameterCall:
+ li.w $t0, BIT2 // IE
+ csrxchg $zero, $t0, LOONGARCH_CSR_PRMD // Clean PIE
+
+OutOfException:
+ ertn
+# End of ApException
+
+ASM_PFX(DeadLoop):
+ b DeadLoop
+# End of DeadLoop
+.end
diff --git a/OvmfPkg/LoongArchVirt/Sec/SecMain.c b/OvmfPkg/LoongArchVirt/Sec/SecMain.c
new file mode 100644
index 0000000000..a7f4324811
--- /dev/null
+++ b/OvmfPkg/LoongArchVirt/Sec/SecMain.c
@@ -0,0 +1,507 @@
+/** @file
+ Main SEC phase code. Transitions to PEI.
+
+ Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/PeimEntryPoint.h>
+
+#include <Ppi/TemporaryRamSupport.h>
+
+/**
+ temporary memory to permanent memory and do stack switching.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in] TemporaryMemoryBase Temporary Memory Base address.
+ @param[in] PermanentMemoryBase Permanent Memory Base address.
+ @param[in] CopySize The size of memory that needs to be migrated.
+
+ @retval EFI_SUCCESS Migration successful.
+**/
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+ TemporaryRamMigration
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamSupportPpiGuid,
+ &mTemporaryRamSupportPpi
+ },
+};
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ The Instance parameter indicates which instance of the section
+ type to return. (0 is first instance, 1 is second...)
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[in] Instance The section instance number
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+**/
+EFI_STATUS
+FindFfsSectionInstance (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN Instance,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfSections;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ //
+ // Loop through the FFS file sections within the PEI Core FFS file
+ //
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)Sections;
+ EndOfSections = EndOfSection + SizeOfSections;
+ for ( ; ; ) {
+ if (EndOfSection == EndOfSections) {
+ break;
+ }
+
+ CurrentAddress = (EndOfSection + 3) & ~(3ULL);
+ if (CurrentAddress >= EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;
+
+ Size = SECTION_SIZE (Section);
+ if (Size < sizeof (*Section)) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the requested section type
+ //
+ if (Section->Type == SectionType) {
+ if (Instance == 0) {
+ *FoundSection = Section;
+ return EFI_SUCCESS;
+ } else {
+ Instance--;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+**/
+EFI_STATUS
+FindFfsSectionInSections (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ return FindFfsSectionInstance (
+ Sections,
+ SizeOfSections,
+ SectionType,
+ 0,
+ FoundSection
+ );
+}
+
+/**
+ Locates a FFS file with the specified file type and a section
+ within that file with the specified section type.
+
+ @param[in] Fv The firmware volume to search
+ @param[in] FileType The file type to locate
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+**/
+EFI_STATUS
+FindFfsFileAndSection (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ IN EFI_FV_FILETYPE FileType,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+
+ if (Fv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Fv;
+ EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
+ CurrentAddress = (EndOfFile + 7) & ~(7ULL);
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;
+ Size = *(UINT32 *)File->Size & 0xffffff;
+ if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the request file type
+ //
+ if (File->Type != FileType) {
+ continue;
+ }
+
+ Status = FindFfsSectionInSections (
+ (VOID *)(File + 1),
+ (UINTN)EndOfFile - (UINTN)(File + 1),
+ SectionType,
+ FoundSection
+ );
+ if (!EFI_ERROR (Status) ||
+ (Status == EFI_VOLUME_CORRUPTED))
+ {
+ return Status;
+ }
+ }
+}
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+**/
+EFI_STATUS
+FindPeiCoreImageBaseInFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_COMMON_SECTION_HEADER *Section;
+
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_PE32,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_TE,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
+ return Status;
+ }
+ }
+
+ *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
+ return EFI_SUCCESS;
+}
+
+/**
+ Find and return Pei Core entry point.
+
+ It also find SEC and PEI Core file debug information. It will report them if
+ remote debug is enabled.
+**/
+VOID
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase = 0;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ Status = FindPeiCoreImageBaseInFv (*BootFirmwareVolumePtr, &PeiCoreImageBase);
+ ASSERT (Status == EFI_SUCCESS);
+
+ ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+
+ //
+ // Report PEI Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Find PEI Core entry point
+ //
+ Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint);
+ if (EFI_ERROR (Status)) {
+ *PeiCoreEntryPoint = 0;
+ }
+
+ return;
+}
+
+/**
+ Find the peicore entry point and jump to the entry point to execute.
+
+ @param[in] Context The first input parameter of InitializeDebugAgent().
+**/
+VOID
+EFIAPI
+SecStartupPhase2 (
+ IN VOID *Context
+ )
+{
+ EFI_SEC_PEI_HAND_OFF *SecCoreData;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFv;
+ EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
+
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
+
+ //
+ // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
+ // is enabled.
+ //
+ BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
+ FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
+ SecCoreData->BootFirmwareVolumeBase = BootFv;
+ SecCoreData->BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;
+
+ DEBUG ((DEBUG_INFO, "Find Pei EntryPoint=%p\n", PeiCoreEntryPoint));
+
+ //
+ // Transfer the control to the PEI core
+ //
+ DEBUG ((DEBUG_INFO, "SecStartupPhase2 %p\n", PeiCoreEntryPoint));
+
+ (*PeiCoreEntryPoint)(SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
+
+ //
+ // If we get here then the PEI Core returned, which is not recoverable.
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+/**
+ Entry point to the C language phase of SEC. initialize some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param[in] BootFv The pointer to the PEI FV in memory.
+ @param[in] TopOfCurrentStack Top of Current Stack.
+**/
+VOID
+EFIAPI
+SecCoreStartupWithStack (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
+ IN VOID *TopOfCurrentStack
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ EFI_FIRMWARE_VOLUME_HEADER *BootPeiFv = (EFI_FIRMWARE_VOLUME_HEADER *)BootFv;
+
+ DEBUG ((DEBUG_INFO, "Entering C environment\n"));
+
+ ProcessLibraryConstructorList (NULL, NULL);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "SecCoreStartupWithStack (0x%lx, 0x%lx)\n",
+ (UINTN)BootFv,
+ (UINTN)TopOfCurrentStack
+ ));
+ DEBUG ((
+ DEBUG_INFO,
+ "(0x%lx, 0x%lx)\n",
+ (UINTN)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase)),
+ (UINTN)(FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
+ ));
+
+ // |-------------| <-- TopOfCurrentStack
+ // | BSP Stack | 32k
+ // |-------------|
+ // | BSP Heap | 32k
+ // |-------------| <-- SecCoreData.TemporaryRamBase
+ // | Ap Stack | 384k
+ // |-------------|
+ // | Exception | 64k
+ // |-------------| <-- PcdOvmfSecPeiTempRamBase
+
+ ASSERT (
+ (UINTN)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase) +
+ FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) ==
+ (UINTN)TopOfCurrentStack
+ );
+
+ //
+ // Initialize SEC hand-off state
+ //
+ SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
+
+ SecCoreData.TemporaryRamSize = (UINTN)SIZE_64KB;
+ SecCoreData.TemporaryRamBase = (VOID *)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) - SecCoreData.TemporaryRamSize);
+
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
+
+ SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
+
+ SecCoreData.BootFirmwareVolumeBase = BootPeiFv;
+ SecCoreData.BootFirmwareVolumeSize = (UINTN)BootPeiFv->FvLength;
+
+ DEBUG ((
+ DEBUG_INFO,
+ "&SecCoreData.BootFirmwareVolumeBase=%lx SecCoreData.BootFirmwareVolumeBase=%lx\n",
+ (UINT64)&(SecCoreData.BootFirmwareVolumeBase),
+ (UINT64)(SecCoreData.BootFirmwareVolumeBase)
+ ));
+ DEBUG ((
+ DEBUG_INFO,
+ "&SecCoreData.BootFirmwareVolumeSize=%lx SecCoreData.BootFirmwareVolumeSize=%lx\n",
+ (UINT64)&(SecCoreData.BootFirmwareVolumeSize),
+ (UINT64)(SecCoreData.BootFirmwareVolumeSize)
+ ));
+
+ //
+ // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL);
+ SecStartupPhase2 (&SecCoreData);
+}
+
+/**
+ temporary memory to permanent memory and do stack switching.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in] TemporaryMemoryBase Temporary Memory Base address.
+ @param[in] PermanentMemoryBase Permanent Memory Base address.
+ @param[in] CopySize The size of memory that needs to be migrated.
+
+ @retval EFI_SUCCESS Migration successful.
+**/
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ VOID *OldHeap;
+ VOID *NewHeap;
+ VOID *OldStack;
+ VOID *NewStack;
+ BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
+
+ DEBUG ((
+ DEBUG_INFO,
+ "TemporaryRamMigration (0x%Lx, 0x%Lx, 0x%Lx)\n",
+ TemporaryMemoryBase,
+ PermanentMemoryBase,
+ (UINT64)CopySize
+ ));
+
+ OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+ OldStack = (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+ NewStack = (VOID *)(UINTN)PermanentMemoryBase;
+
+ //
+ // Migrate Heap
+ //
+ CopyMem (NewHeap, OldHeap, CopySize >> 1);
+
+ //
+ // Migrate Stack
+ //
+ CopyMem (NewStack, OldStack, CopySize >> 1);
+
+ // Use SetJump ()/LongJump () to switch to a new stack.
+ //
+ if (SetJump (&JumpBuffer) == 0) {
+ JumpBuffer.SP = JumpBuffer.SP - (UINTN)OldStack + (UINTN)NewStack;
+ LongJump (&JumpBuffer, (UINTN)-1);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/LoongArchVirt/Sec/SecMain.inf b/OvmfPkg/LoongArchVirt/Sec/SecMain.inf
new file mode 100644
index 0000000000..af29ba0551
--- /dev/null
+++ b/OvmfPkg/LoongArchVirt/Sec/SecMain.inf
@@ -0,0 +1,53 @@
+## @file
+# SEC Driver
+#
+# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecMain
+ FILE_GUID = 57d02d4f-5a5d-4bfa-b7d6-ba0a4d2c72ce
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+#
+# VALID_ARCHITECTURES = LOONGARCH64
+#
+
+[Sources]
+ LoongArch64/Start.S
+ SecMain.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CpuExceptionHandlerLib
+ DebugAgentLib
+ DebugLib
+ IoLib
+ PcdLib
+ PeCoffLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
+
+[FixedPcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuExceptionVectorBaseAddress
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
--
2.27.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#113267): https://edk2.groups.io/g/devel/message/113267
Mute This Topic: https://groups.io/mt/103540134/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-01-05 9:46 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-05 9:41 [edk2-devel] [PATCH v6 00/36] Enable LoongArch virtual machine in edk2 Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 01/36] MdePkg: Add the header file named Csr.h for LoongArch64 Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 02/36] MdePkg: Add LoongArch64 FPU function set into BaseCpuLib Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 03/36] MdePkg: Add LoongArch64 exception function set into BaseLib Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 04/36] MdePkg: Add LoongArch64 local interrupt " Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 05/36] MdePkg: Add LoongArch Cpucfg function Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 06/36] MdePkg: Add read stable counter operation for LoongArch Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 07/36] MdePkg: Add CSR " Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 08/36] MdePkg: Add IOCSR " Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 09/36] MdePkg: Add a new library named PeiServicesTablePointerLibKs0 Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 10/36] UefiCpuPkg: Add LoongArch64 CPU Timer library Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 11/36] UefiCpuPkg: Add CPU exception library for LoongArch Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 12/36] UefiCpuPkg: Add CpuMmuLib.h to UefiCpuPkg Chao Li
2024-01-05 12:49 ` Ni, Ray
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 13/36] UefiCpuPkg: Add LoongArch64CpuMmuLib " Chao Li
2024-01-05 12:50 ` Ni, Ray
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 14/36] UefiCpuPkg: Add multiprocessor library for LoongArch64 Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 15/36] UefiCpuPkg: Add CpuDxe driver " Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 16/36] EmbeddedPkg: Add PcdPrePiCpuIoSize width for LOONGARCH64 Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 17/36] ArmVirtPkg: Move PCD of FDT base address and FDT padding to OvmfPkg Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 18/36] UefiCpuPkg: Add a new CPU IO 2 driver named CpuMmio2Dxe Chao Li
2024-01-06 3:20 ` Ni, Ray
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 19/36] ArmVirtPkg: Enable CpuMmio2Dxe Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 20/36] OvmfPkg/RiscVVirt: " Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 21/36] OvmfPkg/RiscVVirt: Remove PciCpuIo2Dxe from RiscVVirt Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 22/36] ArmVirtPkg: Move the FdtSerialPortAddressLib to OvmfPkg Chao Li
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 23/36] ArmVirtPkg: Move two PCD variables into OvmfPkg Chao Li
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 24/36] ArmVirtPkg: Move PlatformBootManagerLib to OvmfPkg Chao Li
2024-01-08 14:02 ` Laszlo Ersek
2024-01-09 6:40 ` Chao Li
2024-01-09 8:00 ` Laszlo Ersek
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 25/36] OvmfPkg/LoongArchVirt: Add stable timer driver Chao Li
2024-01-12 7:05 ` maobibo
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 26/36] OvmfPkg/LoongArchVirt: Add a NULL library named CollectApResouceLibNull Chao Li
2024-01-10 1:24 ` maobibo
2024-01-10 2:47 ` Chao Li
2024-01-10 9:35 ` maobibo
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 27/36] OvmfPkg/LoongArchVirt: Add serial port hook library Chao Li
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 28/36] OvmfPkg/LoongArchVirt: Add the early serial port output library Chao Li
2024-01-10 1:25 ` maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 29/36] OvmfPkg/LoongArchVirt: Add real time clock library Chao Li
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 30/36] OvmfPkg/LoongArchVirt: Add NorFlashQemuLib Chao Li
2024-01-10 1:26 ` maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 31/36] OvmfPkg/LoongArchVirt: Add FdtQemuFwCfgLib Chao Li
2024-01-10 1:27 ` maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 32/36] OvmfPkg/LoongArchVirt: Add reset system library Chao Li
2024-01-05 9:46 ` Chao Li [this message]
2024-01-08 6:51 ` [edk2-devel] [PATCH v6 33/36] OvmfPkg/LoongArchVirt: Support SEC phase maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 34/36] OvmfPkg/LoongArchVirt: Support PEI phase Chao Li
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 35/36] OvmfPkg/LoongArchVirt: Add build file Chao Li
2024-01-10 1:28 ` maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 36/36] OvmfPkg/LoongArchVirt: Add self introduction file Chao Li
2024-01-10 1:28 ` maobibo
2024-01-08 1:35 ` [edk2-devel] 回复: [PATCH v6 00/36] Enable LoongArch virtual machine in edk2 gaoliming via groups.io
2024-01-08 2:41 ` Chao Li
[not found] ` <17A76A50519959EC.16812@groups.io>
2024-01-08 3:21 ` [edk2-devel] [PATCH v6 19/36] ArmVirtPkg: Enable CpuMmio2Dxe Chao Li
[not found] ` <17A76A543E440C35.16812@groups.io>
2024-01-08 3:24 ` [edk2-devel] [PATCH v6 22/36] ArmVirtPkg: Move the FdtSerialPortAddressLib to OvmfPkg Chao Li
[not found] ` <17A76A5F07C7435C.16812@groups.io>
2024-01-08 3:24 ` [edk2-devel] [PATCH v6 23/36] ArmVirtPkg: Move two PCD variables into OvmfPkg Chao Li
[not found] ` <17A76A601F9A93F4.25044@groups.io>
2024-01-08 3:25 ` [edk2-devel] [PATCH v6 24/36] ArmVirtPkg: Move PlatformBootManagerLib to OvmfPkg Chao Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240105094634.2282358-1-lichao@loongson.cn \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox