From: "Chao Li" <lichao@loongson.cn>
To: devel@edk2.groups.io, maobibo@loongson.cn
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>,
Xianglai Li <lixianglai@loongson.cn>
Subject: Re: [edk2-devel] [PATCH v5 33/36] OvmfPkg/LoongArchVirt: Support SEC phase
Date: Thu, 4 Jan 2024 14:28:29 +0800 [thread overview]
Message-ID: <c25fc73f-577f-4866-a682-621aad0da845@loongson.cn> (raw)
In-Reply-To: <f656d050-2dfe-a362-7f95-563e5a702995@loongson.cn>
[-- Attachment #1: Type: text/plain, Size: 28768 bytes --]
Hi Bibo,
Here are my comments:
Thanks,
Chao
On 2024/1/4 09:49, maobibo wrote:
>
>
> 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 <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>
>> 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 | 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.<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
>> +
>> + /* 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?
There are some mistake in the order between setting up exception base
and copying the exception code, I will fix them in V6.
>
>> +
>> + /* 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.
Yes, there are some issues, in V6 I will add logic to jump to kernel in
ApException.
>> +
>> +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?
In the linux kernel, the IPI vector 0 is used for the SMP boot CPU, I
beleve the documentation for multi-processor is coming soon, it is on
the way.
>
> 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.<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
>>
>
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#113136): https://edk2.groups.io/g/devel/message/113136
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]
-=-=-=-=-=-=-=-=-=-=-=-
[-- Attachment #2: Type: text/html, Size: 45995 bytes --]
next prev parent reply other threads:[~2024-01-04 6:28 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-28 10:03 [edk2-devel] [PATCH v5 00/36] Enable LoongArch virtual machine in edk2 Chao Li
2023-12-28 10:04 ` [edk2-devel] [PATCH v5 01/36] MdePkg: Add the header file named Csr.h for LoongArch64 Chao Li
2023-12-28 10:04 ` [edk2-devel] [PATCH v5 02/36] MdePkg: Add LoongArch64 FPU function set into BaseCpuLib Chao Li
2023-12-28 10:04 ` [edk2-devel] [PATCH v5 03/36] MdePkg: Add LoongArch64 exception function set into BaseLib Chao Li
2023-12-28 10:05 ` [edk2-devel] [PATCH v5 04/36] MdePkg: Add LoongArch64 local interrupt " Chao Li
2023-12-28 10:05 ` [edk2-devel] [PATCH v5 06/36] MdePkg: Add read stable counter operation for LoongArch Chao Li
2023-12-28 10:05 ` [edk2-devel] [PATCH v5 07/36] MdePkg: Add CSR " Chao Li
2023-12-28 10:05 ` [edk2-devel] [PATCH v5 08/36] MdePkg: Add IOCSR " Chao Li
2023-12-28 10:05 ` [edk2-devel] [PATCH v5 09/36] MdePkg: Add a new library named PeiServicesTablePointerLibKs0 Chao Li
2023-12-28 10:05 ` [edk2-devel] [PATCH v5 10/36] UefiCpuPkg: Add LoongArch64 CPU Timer library Chao Li
2023-12-28 10:05 ` [edk2-devel] [PATCH v5 11/36] UefiCpuPkg: Add CPU exception library for LoongArch Chao Li
2023-12-28 10:05 ` [edk2-devel] [PATCH v5 12/36] UefiCpuPkg: Add CpuMmuLib.h to UefiCpuPkg Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 13/36] UefiCpuPkg: Add LoongArch64CpuMmuLib " Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 14/36] UefiCpuPkg: Add multiprocessor library for LoongArch64 Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 15/36] UefiCpuPkg: Add CpuDxe driver " Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 16/36] EmbeddedPkg: Add PcdPrePiCpuIoSize width for LOONGARCH64 Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 17/36] ArmVirtPkg: Move PCD of FDT base address and FDT padding to OvmfPkg Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 18/36] UefiCpuPkg: Add a new CPU IO 2 driver named CpuMmio2Dxe Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 19/36] ArmVirtPkg: Enable CpuMmio2Dxe Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 20/36] OvmfPkg/RiscVVirt: " Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 21/36] OvmfPkg/RiscVVirt: Remove PciCpuIo2Dxe from RiscVVirt Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 22/36] ArmVirtPkg: Move the FdtSerialPortAddressLib to OvmfPkg Chao Li
2023-12-28 10:06 ` [edk2-devel] [PATCH v5 23/36] ArmVirtPkg: Move PcdTerminalTypeGuidBuffer and PcdUninstallMemAttrProtocol into OvmfPkg Chao Li
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 24/36] ArmVirtPkg: Move PlatformBootManagerLib to OvmfPkg Chao Li
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 25/36] OvmfPkg/LoongArchVirt: Add stable timer driver Chao Li
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 26/36] OvmfPkg/LoongArchVirt: Add a NULL library named CollectApResouceLibNull Chao Li
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 27/36] OvmfPkg/LoongArchVirt: Add serial port hook library Chao Li
2024-01-03 10:07 ` maobibo
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 28/36] OvmfPkg/LoongArchVirt: Add the early serial port output library Chao Li
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 29/36] OvmfPkg/LoongArchVirt: Add real time clock library Chao Li
2024-01-03 10:07 ` maobibo
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 30/36] OvmfPkg/LoongArchVirt: Add NorFlashQemuLib Chao Li
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 31/36] OvmfPkg/LoongArchVirt: Add FdtQemuFwCfgLib Chao Li
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 32/36] OvmfPkg/LoongArchVirt: Add reset system library Chao Li
2024-01-04 1:28 ` maobibo
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 33/36] OvmfPkg/LoongArchVirt: Support SEC phase Chao Li
2024-01-04 1:49 ` maobibo
2024-01-04 6:28 ` Chao Li [this message]
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 34/36] OvmfPkg/LoongArchVirt: Support PEI phase Chao Li
2024-01-03 8:12 ` maobibo
2023-12-28 10:07 ` [edk2-devel] [PATCH v5 35/36] OvmfPkg/LoongArchVirt: Add build file Chao Li
2023-12-28 10:08 ` [edk2-devel] [PATCH v5 36/36] OvmfPkg/LoongArchVirt: Add self introduction file Chao Li
[not found] ` <17A4F6E18EBFD408.18542@groups.io>
2023-12-29 6:27 ` [edk2-devel] [PATCH v5 20/36] OvmfPkg/RiscVVirt: Enable CpuMmio2Dxe 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=c25fc73f-577f-4866-a682-621aad0da845@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