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 1652C94145D for ; Mon, 8 Jan 2024 06:52:03 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=xui/NyyHkA40sXHGnCiXFCNbAOXjQyPE7MxWhnBSM+M=; 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=1704696722; v=1; b=FomfIxyXcmluFb6qcvfUz7s2SHPwIbjRlI3CY8TU6/VGEiVV1hFGRZ4dekeDsT9eSt/hr0gg wBFNuPK2RbX3TBsTW8e9bHY9G7+SAwloHqMYxY9EgCZo92eq6UeHsp3OjQU4/k2AKQ2V0ZJxbQO tyWEPZEvbJhRED77ekv0eU74= X-Received: by 127.0.0.2 with SMTP id THrTYY7687511xTSspBXT4S8; Sun, 07 Jan 2024 22:52:02 -0800 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.1596.1704696719797558106 for ; Sun, 07 Jan 2024 22:52:02 -0800 X-Received: from loongson.cn (unknown [10.20.42.173]) by gateway (Coremail) with SMTP id _____8BxHLuEm5tl5wwDAA--.1678S3; Mon, 08 Jan 2024 14:51:48 +0800 (CST) X-Received: from [10.20.42.173] (unknown [10.20.42.173]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxmd1_m5tl4x0HAA--.18502S3; Mon, 08 Jan 2024 14:51:45 +0800 (CST) Subject: Re: [edk2-devel] [PATCH v6 33/36] OvmfPkg/LoongArchVirt: Support SEC phase To: Chao Li , devel@edk2.groups.io Cc: Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Dongyan Qian , Xianglai Li References: <20240105094118.2279380-1-lichao@loongson.cn> <20240105094634.2282358-1-lichao@loongson.cn> From: "maobibo" Message-ID: Date: Mon, 8 Jan 2024 14:51:43 +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: <20240105094634.2282358-1-lichao@loongson.cn> X-CM-TRANSID: AQAAf8Dxmd1_m5tl4x0HAA--.18502S3 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBj9fXoWfCr1rWF4kuw45JFykAF13GFX_yoW8tw1xZo W7u3Zayw4rJr15Z34kGrn7Xr4Ut3WS9a98trWrXryDGF40yFyYka92qw4DKw1rGan5XF98 G3yfJa48JFWSqF1rl-sFpf9Il3svdjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYs7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUXVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26F4j6r4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E 14v26r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020Ex4CE44 I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JrI_JrylYx0Ex4A2 jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvEwIxGrwCYjI0SjxkI62 AI1cAE67vIY487MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E 5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtV W8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26ryj6F1UMIIF0xvE2Ix0cI8IcVCY 1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI 0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7I U8j-e5UUUUU== 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: 5CnSGCx9tdK2Cpbdf7pBmncvx7686176AA= 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=FomfIxyX; 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 2024/1/5 下午5:46, 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 > Cc: Bibo Mao > Cc: Dongyan Qian > Signed-off-by: Chao Li > Co-authored-by: Xianglai Li > Co-authored-by: Bibo Mao > --- > 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.
> +# > +# 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 > + > + /* 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.
> + > + 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 > Reviewed-by: Bibo Mao -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113360): https://edk2.groups.io/g/devel/message/113360 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] -=-=-=-=-=-=-=-=-=-=-=-