[edk2-devel] [edk2-platforms][PATCH V5 02/15] Platform/Loongson: Support SEC

Chao Li lichao at loongson.cn
Fri Nov 11 09:35:36 UTC 2022


Reviewed-by: Chao Li <lichao at loongson.cn>

Thanks,
Chao
--------

On 11月 11 2022, at 5:12 下午, xianglai li <lixianglai at loongson.cn> wrote:
> Add SEC Code And Readme.md for LoongArchQemu
>
>
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4054
>
>
> Cc: Bibo Mao <maobibo at loongson.cn>
> Cc: Chao Li <lichao at loongson.cn>
> Cc: Leif Lindholm <quic_llindhol at quicinc.com>
> Cc: Liming Gao <gaoliming at byosoft.com.cn>
> Cc: Michael D Kinney <michael.d.kinney at intel.com>
> Signed-off-by: xianglai li <lixianglai at loongson.cn>
> Signed-off-by: xianglai li <lixianglai at loongson.cn>
> ---
> .../Include/LoongArchQemuPlatform.h | 2 +-
> .../Loongson/LoongArchQemuPkg/Loongson.dec | 38 ++
> .../Loongson/LoongArchQemuPkg/Loongson.dsc | 122 +++++
> .../Loongson/LoongArchQemuPkg/Loongson.fdf | 53 ++
> .../LoongArchQemuPkg/Loongson.fdf.inc | 21 +
> .../LoongArchQemuPkg/Sec/LoongArch64/Start.S | 84 +++
> .../Loongson/LoongArchQemuPkg/Sec/SecMain.c | 494 ++++++++++++++++++
> .../Loongson/LoongArchQemuPkg/Sec/SecMain.inf | 51 ++
> 8 files changed, 864 insertions(+), 1 deletion(-)
> create mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.dec
> create mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
> create mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
> create mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc
> create mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.S
> create mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.c
> create mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf
>
>
> diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.h b/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.h
> index e942e6a994..d003b9013d 100644
> --- a/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.h
> +++ b/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.h
> @@ -92,4 +92,4 @@
> #define UART_BASE_ADDRESS (0x1fe001e0)
> #define UART_BPS (115200)
> #define UART_WAIT_TIMOUT (1000000)
> -#endif
> +#endif // LOONGARCH_QEMU_PLATFORM_H_
> diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dec b/Platform/Loongson/LoongArchQemuPkg/Loongson.dec
> new file mode 100644
> index 0000000000..61f600b20d
> --- /dev/null
> +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dec
> @@ -0,0 +1,38 @@
> +## @file
> +#
> +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + DEC_SPECIFICATION = 0x00010005
> + PACKAGE_NAME = LoongArchQemuPkg
> + PACKAGE_GUID = b51d765a-41da-45fc-a537-de3ee785c0f6
> + PACKAGE_VERSION = 0.1
> +
> +################################################################################
> +#
> +# Include Section - list of Include Paths that are provided by this package.
> +# Comments are used for Keywords and Module Types.
> +#
> +# Supported Module Types:
> +# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
> +# DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
> +#
> +################################################################################
> +[Includes.common]
> + Include # Root include for the package
> +
> +[Guids]
> + gLoongArchQemuPkgTokenSpaceGuid = { 0x0e0383ce, 0x0151, 0x4d01, { 0x80, 0x0e, 0x3f, 0xef, 0x8b, 0x27, 0x6d, 0x52 } }
> +
> +## In the PcdsFixedAtBuild and PcdsDynamic areas, numbers start at 0x0.
> +[PcdsFixedAtBuild, PcdsDynamic]
> + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvBase|0x0|UINT64|0x00000000
> + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvSize|0x0|UINT32|0x00000001
> + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase|0|UINT64|0x0000000b
> + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize|0|UINT32|0x0000000c
> + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase|0x0|UINT64|0x0000000f
> + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvSize|0x0|UINT32|0x00000010
> diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
> new file mode 100644
> index 0000000000..b506f70625
> --- /dev/null
> +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
> @@ -0,0 +1,122 @@
> +## @file
> +#
> +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +################################################################################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +###############################################################################
> +[Defines]
> + PLATFORM_NAME = LoongArchQemu
> + PLATFORMPKG_NAME = LoongArchQemu
> + PLATFORM_GUID = 7926ea52-b0dc-4ee8-ac63-341eebd84ed4
> + PLATFORM_VERSION = 0.1
> + DSC_SPECIFICATION = 0x00010005
> + OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
> + SUPPORTED_ARCHITECTURES = LOONGARCH64
> + BUILD_TARGETS = DEBUG|RELEASE
> + SKUID_IDENTIFIER = DEFAULT
> + FLASH_DEFINITION = Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
> + TTY_TERMINAL = FALSE
> +
> +############################################################################
> +#
> +# Defines for default states. These can be changed on the command line.
> +# -D FLAG=VALUE
> +############################################################################
> +[BuildOptions]
> + GCC:RELEASE_*_*_CC_FLAGS = -DSPEEDUP
> +
> + #
> + # Disable deprecated APIs.
> + #
> + GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
> +
> +[BuildOptions.LOONGARCH64.EDKII.SEC]
> + *_*_*_CC_FLAGS =
> +
> +[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION]
> + GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
> + GCC:*_*_LOONGARCH64_DLINK_FLAGS = -z common-page-size=0x10000
> +
> +################################################################################
> +#
> +# Library Class section - list of all Library Classes needed by this Platform.
> +#
> +################################################################################
> +
> +!include MdePkg/MdeLibs.dsc.inc
> +
> +[LibraryClasses.common]
> + PcdLib | MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> + PrintLib | MdePkg/Library/BasePrintLib/BasePrintLib.inf
> + BaseMemoryLib | MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> + BaseLib | MdePkg/Library/BaseLib/BaseLib.inf
> + PeCoffLib | MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> + IoLib | MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> + SerialPortLib | Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib.inf
> + DebugPrintErrorLevelLib | MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
> + PeCoffExtraActionLib | MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
> + DebugAgentLib | MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
> +
> +################################################################################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
> +#
> +################################################################################
> +[PcdsFixedAtBuild]
> +## BaseLib ##
> + gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength | 1000000
> + gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength | 1000000
> + gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength | 1000000
> +
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0x8000004F
> + # DEBUG_INIT 0x00000001 // Initialization
> + # DEBUG_WARN 0x00000002 // Warnings
> + # DEBUG_LOAD 0x00000004 // Load events
> + # DEBUG_FS 0x00000008 // EFI File system
> + # DEBUG_POOL 0x00000010 // Alloc & Free (pool)
> + # DEBUG_PAGE 0x00000020 // Alloc & Free (page)
> + # DEBUG_INFO 0x00000040 // Informational debug messages
> + # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers
> + # DEBUG_VARIABLE 0x00000100 // Variable
> + # DEBUG_BM 0x00000400 // Boot Manager
> + # DEBUG_BLKIO 0x00001000 // BlkIo Driver
> + # DEBUG_NET 0x00004000 // Network Io Driver
> + # DEBUG_UNDI 0x00010000 // UNDI Driver
> + # DEBUG_LOADFILE 0x00020000 // LoadFile
> + # DEBUG_EVENT 0x00080000 // Event messages
> + # DEBUG_GCD 0x00100000 // Global Coherency Database changes
> + # DEBUG_CACHE 0x00200000 // Memory range cachability changes
> + # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may
> + # DEBUG_ERROR 0x80000000 // Error
> +
> +!if $(TARGET) == RELEASE
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0x21
> +!else
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0x2f
> +!endif
> + # DEBUG_ASSERT_ENABLED 0x01
> + # DEBUG_PRINT_ENABLED 0x02
> + # DEBUG_CODE_ENABLED 0x04
> + # CLEAR_MEMORY_ENABLED 0x08
> + # ASSERT_BREAKPOINT_ENABLED 0x10
> + # ASSERT_DEADLOOP_ENABLED 0x20
> +
> + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase | 0x10000
> + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize | 0x10000
> +
> +[Components]
> +
> + #
> + # SEC Phase modules
> + #
> + Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf
> diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
> new file mode 100644
> index 0000000000..9685795cda
> --- /dev/null
> +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
> @@ -0,0 +1,53 @@
> +## @file
> +#
> +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +#####################################################################################################
> +[Defines]
> +!include Loongson.fdf.inc
> +
> +#####################################################################################################
> +[FD.QEMU_EFI]
> +BaseAddress = $(FD_BASE_ADDRESS)
> +Size = $(FD_SIZE)
> +ErasePolarity = 1
> +BlockSize = $(BLOCK_SIZE)
> +NumBlocks = $(FD_BLOCKS)
> +
> +$(SECFV_OFFSET)|$(SECFV_SIZE)
> +gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase|gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvSize
> +FV = SECFV
> +
> +#####################################################################################################
> +[FV.SECFV]
> +FvNameGuid = 587d4265-5e71-41da-9c35-4258551f1e22
> +BlockSize = $(BLOCK_SIZE)
> +FvAlignment = 16
> +ERASE_POLARITY = 1
> +MEMORY_MAPPED = TRUE
> +STICKY_WRITE = TRUE
> +LOCK_CAP = TRUE
> +LOCK_STATUS = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP = TRUE
> +WRITE_STATUS = TRUE
> +WRITE_LOCK_CAP = TRUE
> +WRITE_LOCK_STATUS = TRUE
> +READ_DISABLED_CAP = TRUE
> +READ_ENABLED_CAP = TRUE
> +READ_STATUS = TRUE
> +READ_LOCK_CAP = TRUE
> +READ_LOCK_STATUS = TRUE
> +
> +INF Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf
> +
> +#####################################################################################################
> +[Rule.Common.SEC]
> + FILE SEC = $(NAMED_GUID) {
> + TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
> + UI STRING ="$(MODULE_NAME)" Optional
> + }
> diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc
> new file mode 100644
> index 0000000000..6f17909748
> --- /dev/null
> +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc
> @@ -0,0 +1,21 @@
> +## @file
> +#
> +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +DEFINE BLOCK_SIZE = 0x1000
> +
> +############################################################################
> +# fd total
> +DEFINE FD_BASE_ADDRESS = 0x1c000000
> +DEFINE FD_BLOCKS = 0x400
> +DEFINE FD_SIZE = 0x400000
> +
> +############################################################################
> +#flash code layout
> +#Set Sec base address and size in flash
> +DEFINE SECFV_OFFSET = 0x00000000
> +DEFINE SECFV_SIZE = 0x00010000
> diff --git a/Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.S b/Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.S
> new file mode 100644
> index 0000000000..5d7ce313c0
> --- /dev/null
> +++ b/Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.S
> @@ -0,0 +1,84 @@
> +#------------------------------------------------------------------------------
> +#
> +# Start for LoongArch
> +#
> +# Copyright (c) 2022 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/Cpu.h>
> +
> +ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
> +ASM_GLOBAL ASM_PFX(DeadLoop)
> +
> +.text
> +ASM_PFX(_ModuleEntryPoint):
> + /* configure reset ebase */
> + la.pcrel T0, DeadLoop
> + csrwr T0, LOONGARCH_CSR_EBASE
> +
> + /*disable interrupt*/
> + li.d T0, (1 << 2)
> + csrxchg ZERO, T0, LOONGARCH_CSR_CRMD
> +
> + /* read physical cpu number id */
> + csrrd T0, LOONGARCH_CSR_CPUNUM
> + andi T0, T0, 0x3ff
> + li.d A0, BOOTCORE_ID //0
> + bne T0, A0, slave_main
> +
> +call_centry:
> + /*call C function make sure parameter true*/
> + li.d A1, FixedPcdGet64(PcdSecPeiTempRamBase) + FixedPcdGet32(PcdSecPeiTempRamSize) # stack base
> + li.d A0, FixedPcdGet64(PcdFlashPeiFvBase) # PEI Fv base
> + move SP, A1
> + addi.d SP, SP, -0x8
> + bl SecCoreStartupWithStack
> +
> +slave_main:
> + # clear mailbox
> + li.d T1, LOONGSON_CSR_MAIL_BUF0
> + iocsrwr.d ZERO, T1
> +
> + # enable IPI interrupt
> + li.d T0, (1 << 12)
> + csrxchg T0, T0, LOONGARCH_CSR_ECFG
> +
> + addi.d T0, ZERO, -1
> + li.d T1, LOONGSON_IOCSR_IPI_EN
> + iocsrwr.w T0, T1
> +
> +1:
> + # wait for wakeup
> + idle 0
> + nop
> + iocsrrd.w T0, T1
> + beqz T0, 1b
> +
> + # read and clear ipi interrupt
> + li.d T1, LOONGSON_IOCSR_IPI_STATUS
> + iocsrrd.w T0, T1
> + li.d T1, LOONGSON_IOCSR_IPI_CLEAR
> + iocsrwr.w T0, T1
> +
> + # 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, LOONGSON_CSR_MAIL_BUF0
> + iocsrrd.d T0, T1
> + or RA, T0, ZERO
> + jirl ZERO, RA, 0x0
> +
> +.align 12
> +ASM_PFX(DeadLoop):
> + b DeadLoop
> diff --git a/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.c b/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.c
> new file mode 100644
> index 0000000000..3f1998c48c
> --- /dev/null
> +++ b/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.c
> @@ -0,0 +1,494 @@
> +/** @file
> + Main SEC phase code. Transitions to PEI.
> +
> + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugAgentLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeCoffLib.h>
> +#include <Library/PeCoffGetEntryPointLib.h>
> +#include <Library/PeCoffExtraActionLib.h>
> +#include <Library/ExtractGuidedSectionLib.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) (PcdGet64 (PcdSecPeiTempRamBase)),
> + (UINTN) (PcdGet32 (PcdSecPeiTempRamSize))
> + ));
> +
> + // |-------------| <-- TopOfCurrentStack
> + // | Stack | 32k
> + // |-------------|
> + // | Heap | 32k
> + // |-------------| <-- SecCoreData.TemporaryRamBase
> + //
> +
> + ASSERT ((UINTN) (PcdGet64 (PcdSecPeiTempRamBase) +
> + PcdGet32 (PcdSecPeiTempRamSize)) ==
> + (UINTN) TopOfCurrentStack);
> +
> + //
> + // Initialize SEC hand-off state
> + //
> + SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
> +
> + SecCoreData.TemporaryRamSize = (UINTN) PcdGet32 (PcdSecPeiTempRamSize);
> + SecCoreData.TemporaryRamBase = (VOID *) PcdGet64 (PcdSecPeiTempRamBase);
> +
> + 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/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf b/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf
> new file mode 100644
> index 0000000000..c0d5439d53
> --- /dev/null
> +++ b/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# SEC Driver
> +#
> +# Copyright (c) 2022 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]
> + Platform/Loongson/LoongArchQemuPkg/Loongson.dec
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + BaseMemoryLib
> + PcdLib
> + DebugAgentLib
> + IoLib
> + PeCoffLib
> + PeCoffGetEntryPointLib
> + PeCoffExtraActionLib
> +
> +[Ppis]
> + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> +
> +[FixedPcd]
> + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase
> + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize
> +
> + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase
> + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvSize
> + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvBase
> + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvSize
> --
> 2.31.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#96287): https://edk2.groups.io/g/devel/message/96287
Mute This Topic: https://groups.io/mt/94954837/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/edk2-devel-archive/attachments/20221111/5b37cd70/attachment-0001.htm>


More information about the edk2-devel-archive mailing list