public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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 --]

  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