From nobody Sat Feb 7 05:52:13 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+112976+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+112976+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1703758073; cv=none; d=zohomail.com; s=zohoarc; b=TjylbGKTHEqFcbWFBOOAOLcUw6EM9406QgwMNnKiuZiBywM9sz2GaOeRKT2KsYaRqi7Eekc22bpV3Z7iGDuvbRTK2Nn6UyvRrSqUmAaRDgRMQ7QNB6qsY3tcRP2BMAuclkh6L+MharDT3VZyCgJ32bRGxaC3cMYWL2c9KxvQbqM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1703758073; 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=vLFfVSfoTCOSVlRgog6/3GhN3H05AmPPPnzLG8s78eE=; b=O/oyynEboS6dBPRqpAIsH7RdBcyN2EeTshj60ZQSaNb6Es09ktub2rEAeB5CUc28MjQpZhGKsAu3vEpN/dy6ddppRfiPvZA13DwndEsw3hAlzzxAfTzxLhUKx5/aoRkGQYYts9TtmnjxCe8s+Dc7Ac3W2sEVH+y1W4ZQI3s6ZPw= 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+112976+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1703758073943469.3092541135686; Thu, 28 Dec 2023 02:07:53 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=py6vp9vu+D5wSjbeDecU7eAj3I6BSFsqMSZ1Q5KTfcw=; 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=1703758073; v=1; b=guof16PsuPswSB0NXWkjC8czPkEUt/hW2bDk4J4dulwE1PmnpKKFY6DwcXQrExp0HrULd3mN z0CXtDI51uJZ04prhqymj4x6hjqwztIzeMHz8kdfOBDsVgus0QvXHDASuwRs1WpG/9+HlWHyiGn UdAkhL2FhrNW8iPgT4DqR27o= X-Received: by 127.0.0.2 with SMTP id q4MxYY1788612xpJ4owi1FFQ; Thu, 28 Dec 2023 02:07:53 -0800 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.120655.1703758072625396607 for ; Thu, 28 Dec 2023 02:07:53 -0800 X-Received: from loongson.cn (unknown [10.2.9.245]) by gateway (Coremail) with SMTP id _____8Cxbev2SI1lowMAAA--.67S3; Thu, 28 Dec 2023 18:07:50 +0800 (CST) X-Received: from code-server.gen (unknown [10.2.9.245]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxG+T0SI1ljwUOAA--.47773S2; Thu, 28 Dec 2023 18:07:49 +0800 (CST) From: "Chao Li" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Xianglai Li , Bibo Mao Subject: [edk2-devel] [PATCH v5 33/36] OvmfPkg/LoongArchVirt: Support SEC phase Date: Thu, 28 Dec 2023 18:07:48 +0800 Message-Id: <20231228100748.1766749-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: AQAAf8BxG+T0SI1ljwUOAA--.47773S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQATCGWM2y8KPQA3sH 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: Xfku6AlxsYxRWXUkOHoIQ5urx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1703758074362100001 Content-Type: text/plain; charset="utf-8" Add SEC code for LoongArch virtual machine. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Signed-off-by: Chao Li Co-authored-by: Xianglai Li Co-authored-by: Bibo Mao --- OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S | 183 +++++++ OvmfPkg/LoongArchVirt/Sec/SecMain.c | 507 ++++++++++++++++++ OvmfPkg/LoongArchVirt/Sec/SecMain.inf | 53 ++ 3 files changed, 743 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/LoongA= rchVirt/Sec/LoongArch64/Start.S new file mode 100644 index 0000000000..145f8ffc59 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S @@ -0,0 +1,183 @@ +#-------------------------------------------------------------------------= ----- +# +# Start for Loongson LoongArch processor +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Glossary: +# - CSR - CPU Status Register +# - EBASE - Exception Base Address +#-------------------------------------------------------------------------= ----- +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include +#include +#include + +#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 + + /* Configure BSP reset ebase */ + li.d $a0, FixedPcdGet64(PcdCpuExceptionVectorBaseAddress) + bl SetExceptionBaseAddress + move $t1, $a0 + + /* Set BSP stack */ + li.d $t0, FixedPcdGet64(PcdOvmfSecPeiTempRamBase) + FixedPcdGet32(Pc= dOvmfSecPeiTempRamSize) # stack base + move $sp, $t0 + addi.d $sp, $sp, -0x8 + + /* 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, $t1 + bl CopyMem + +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=20 + 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(PcdO= vmfSecPeiTempRamSize) - 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 + li.d $t1, LOONGARCH_IOCSR_MBUF0 + iocsrrd.w $t2, $t1 + beqz $t2, WaitForWake + + /* Disable global interrupt */ + bl DisableInterrupts + + /* Disable IPI interrupt */ + li.d $t0, (1 << 12) + csrxchg $zero, $t0, LOONGARCH_CSR_ECFG + + /* Read mail buf and jump to specified entry */ + li.d $t1, LOONGARCH_IOCSR_MBUF0 + iocsrrd.d $t0, $t1 + li.d $t1, LOONGARCH_IOCSR_MBUF3 + iocsrrd.d $a1, $t1 + 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 +NoParameterCall: + move $ra, $t0 + jirl $zero, $ra, 0x0 +# 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 + ertn +# End of ApException + +ASM_PFX(DeadLoop): + b DeadLoop +# End of DeadLoop +.end diff --git a/OvmfPkg/LoongArchVirt/Sec/SecMain.c b/OvmfPkg/LoongArchVirt/Se= c/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 r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + 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 =3D { + TemporaryRamMigration +}; + +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] =3D { + { + (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 =3D (EFI_PHYSICAL_ADDRESS)(UINTN)Sections; + EndOfSections =3D EndOfSection + SizeOfSections; + for ( ; ; ) { + if (EndOfSection =3D=3D EndOfSections) { + break; + } + + CurrentAddress =3D (EndOfSection + 3) & ~(3ULL); + if (CurrentAddress >=3D EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + + Section =3D (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress; + + Size =3D SECTION_SIZE (Section); + if (Size < sizeof (*Section)) { + return EFI_VOLUME_CORRUPTED; + } + + EndOfSection =3D CurrentAddress + Size; + if (EndOfSection > EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + + // + // Look for the requested section type + // + if (Section->Type =3D=3D SectionType) { + if (Instance =3D=3D 0) { + *FoundSection =3D 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 !=3D EFI_FVH_SIGNATURE) { + DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", F= v)); + return EFI_VOLUME_CORRUPTED; + } + + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)Fv; + EndOfFirmwareVolume =3D CurrentAddress + Fv->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile =3D CurrentAddress + Fv->HeaderLength; ; ) { + CurrentAddress =3D (EndOfFile + 7) & ~(7ULL); + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_VOLUME_CORRUPTED; + } + + File =3D (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress; + Size =3D *(UINT32 *)File->Size & 0xffffff; + if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) { + return EFI_VOLUME_CORRUPTED; + } + + EndOfFile =3D CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_VOLUME_CORRUPTED; + } + + // + // Look for the request file type + // + if (File->Type !=3D FileType) { + continue; + } + + Status =3D FindFfsSectionInSections ( + (VOID *)(File + 1), + (UINTN)EndOfFile - (UINTN)(File + 1), + SectionType, + FoundSection + ); + if (!EFI_ERROR (Status) || + (Status =3D=3D 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 =3D FindFfsFileAndSection ( + Fv, + EFI_FV_FILETYPE_PEI_CORE, + EFI_SECTION_PE32, + &Section + ); + if (EFI_ERROR (Status)) { + Status =3D 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 =3D (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 the= m 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 =3D 0; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + Status =3D FindPeiCoreImageBaseInFv (*BootFirmwareVolumePtr, &PeiCoreIma= geBase); + ASSERT (Status =3D=3D EFI_SUCCESS); + + ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageB= ase; + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)= ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status =3D PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (= VOID **)PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint =3D 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 =3D (EFI_SEC_PEI_HAND_OFF *)Context; + + // + // Find PEI Core entry point. It will report SEC and Pei Core debug info= rmation if remote debug + // is enabled. + // + BootFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolume= Base; + FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint); + SecCoreData->BootFirmwareVolumeBase =3D BootFv; + SecCoreData->BootFirmwareVolumeSize =3D (UINTN)BootFv->FvLength; + + DEBUG ((DEBUG_INFO, "Find Pei EntryPoint=3D%p\n", PeiCoreEntryPoint)); + + // + // Transfer the control to the PEI core + // + DEBUG ((DEBUG_INFO, "SecStartupPhase2 %p\n", PeiCoreEntryPoint)); + + (*PeiCoreEntryPoint)(SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDis= patchTable); + + // + // 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 me= mory 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 =3D (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)) =3D=3D + (UINTN)TopOfCurrentStack + ); + + // + // Initialize SEC hand-off state + // + SecCoreData.DataSize =3D sizeof (EFI_SEC_PEI_HAND_OFF); + + SecCoreData.TemporaryRamSize =3D (UINTN)SIZE_64KB; + SecCoreData.TemporaryRamBase =3D (VOID *)(FixedPcdGet64 (PcdOvmfSecPeiTe= mpRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) - SecCoreData.Tempora= ryRamSize); + + SecCoreData.PeiTemporaryRamBase =3D SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize =3D SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.StackBase =3D (UINT8 *)SecCoreData.TemporaryRamBase + SecCor= eData.PeiTemporaryRamSize; + SecCoreData.StackSize =3D SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.BootFirmwareVolumeBase =3D BootPeiFv; + SecCoreData.BootFirmwareVolumeSize =3D (UINTN)BootPeiFv->FvLength; + + DEBUG (( + DEBUG_INFO, + "&SecCoreData.BootFirmwareVolumeBase=3D%lx SecCoreData.BootFirmwareVol= umeBase=3D%lx\n", + (UINT64)&(SecCoreData.BootFirmwareVolumeBase), + (UINT64)(SecCoreData.BootFirmwareVolumeBase) + )); + DEBUG (( + DEBUG_INFO, + "&SecCoreData.BootFirmwareVolumeSize=3D%lx SecCoreData.BootFirmwareVol= umeSize=3D%lx\n", + (UINT64)&(SecCoreData.BootFirmwareVolumeSize), + (UINT64)(SecCoreData.BootFirmwareVolumeSize) + )); + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phase= s 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 =3D (VOID *)(UINTN)TemporaryMemoryBase; + NewHeap =3D (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1)); + + OldStack =3D (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1)); + NewStack =3D (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) =3D=3D 0) { + JumpBuffer.SP =3D 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.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SecMain + FILE_GUID =3D 57d02d4f-5a5d-4bfa-b7d6-ba0a4d2c72ce + MODULE_TYPE =3D SEC + VERSION_STRING =3D 1.0 + +# +# VALID_ARCHITECTURES =3D 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 --=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 (#112976): https://edk2.groups.io/g/devel/message/112976 Mute This Topic: https://groups.io/mt/103398640/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-