From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id BAB79780091 for ; Thu, 4 Jan 2024 01:49:31 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=l/Gm9FoP8tDf8u1IEnDc6z4lT6PsL7QsALyX081QPDA=; c=relaxed/simple; d=groups.io; h=Subject:To:Cc:References:From:Message-ID:Date:User-Agent:MIME-Version:In-Reply-To:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type:Content-Language:Content-Transfer-Encoding; s=20140610; t=1704332970; v=1; b=h5uJEhw7zg5R/AmXHmKhWAT/fJkg9C7o4xprmYXAYPaYQQ2p+0+7tibbWlHM8piNA8feml8L jZbjqn8IdsjAm/El2+Te5h8qL0zpgb0lk/IzwR8x0Z9z/pHoiuiulMm27/TRUBKmhGqnjhPt1Jt c5xWCRWhl2rBdBajjCpi459o= X-Received: by 127.0.0.2 with SMTP id LMFAYY7687511xJBNoCt2rFD; Wed, 03 Jan 2024 17:49:30 -0800 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.45039.1704332968329841618 for ; Wed, 03 Jan 2024 17:49:29 -0800 X-Received: from loongson.cn (unknown [10.20.42.173]) by gateway (Coremail) with SMTP id _____8AxDOukDpZlrMsBAA--.6869S3; Thu, 04 Jan 2024 09:49:24 +0800 (CST) X-Received: from [10.20.42.173] (unknown [10.20.42.173]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Axz4efDpZlQCgAAA--.410S3; Thu, 04 Jan 2024 09:49:21 +0800 (CST) Subject: Re: [edk2-devel] [PATCH v5 33/36] OvmfPkg/LoongArchVirt: Support SEC phase To: Chao Li , devel@edk2.groups.io Cc: Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Xianglai Li References: <20231228100351.1756165-1-lichao@loongson.cn> <20231228100748.1766749-1-lichao@loongson.cn> From: "maobibo" Message-ID: Date: Thu, 4 Jan 2024 09:49:19 +0800 User-Agent: Mozilla/5.0 (X11; Linux loongarch64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <20231228100748.1766749-1-lichao@loongson.cn> X-CM-TRANSID: AQAAf8Axz4efDpZlQCgAAA--.410S3 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBj9fXoWfXF4UCryfJw4rXFy5WF47KFX_yoW8Kr4UXo W7u3WSyw4rJr15Z34kGrn7Xw4Ut3WS9a98JFWrXryDGF40yFyYka92qw4DKr1rGan5XF98 G3yfJa48JFWSq3Wrl-sFpf9Il3svdjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUY27kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUGVWUXwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r1j6r4UM28EF7xvwVC2z280aVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4j6r4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAF wI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcVAKI48JMxk0xIA0c2IEe2xFo4 CEbIxvr21l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG 67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMI IYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E 14v26r1j6r4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJV W8JwCI42IY6I8E87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x07j8yCJU UUUU= 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,maobibo@loongson.cn List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: J6RrevDcJG0kzO1yMU2AQ0xcx7686176AA= Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=h5uJEhw7; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io On 2023/12/28 下午6:07, Chao Li wrote: > Add SEC code for LoongArch virtual machine. > > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 > > 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/LoongArchVirt/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 reserved.
> +# > +# 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 what is usage of PcdCpuExceptionVectorBaseAddress about BSP here? Is there actual exception handler in PcdCpuExceptionVectorBaseAddress in sec stage? > + > + /* Set BSP stack */ > + li.d $t0, FixedPcdGet64(PcdOvmfSecPeiTempRamBase) + FixedPcdGet32(PcdOvmfSecPeiTempRamSize) # 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 > + 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 There will be potential problem if ipi interrupt happens after EnableInterrupts and before CpuSleep. > + > +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 What is usage of mail buffer LOONGARCH_IOCSR_MBUF3 here? Do we have documented Multi-processor boot protocol? Regards Bibo Mao > + 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/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.
> + > + 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 = { > + 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.
> +# > +# 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 > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113110): https://edk2.groups.io/g/devel/message/113110 Mute This Topic: https://groups.io/mt/103398640/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-