Thanks,
Chao
--------
Add SEC Code And Readme.md for LoongArchQemuREF: https://bugzilla.tianocore.org/show_bug.cgi?id=4054Cc: Bibo Mao <maobibo@loongson.cn>Cc: Chao Li <lichao@loongson.cn>Cc: Leif Lindholm <quic_llindhol@quicinc.com>Cc: Liming Gao <gaoliming@byosoft.com.cn>Cc: Michael D Kinney <michael.d.kinney@intel.com>Signed-off-by: xianglai li <lixianglai@loongson.cn>Signed-off-by: xianglai li <lixianglai@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.deccreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.dsccreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.fdfcreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inccreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.Screate mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.ccreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.infdiff --git a/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.h b/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.hindex 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.decnew file mode 100644index 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|0x00000010diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc b/Platform/Loongson/LoongArchQemuPkg/Loongson.dscnew file mode 100644index 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.infdiff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdfnew file mode 100644index 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.incnew file mode 100644index 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 = 0x00010000diff --git a/Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.S b/Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.Snew file mode 100644index 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 DeadLoopdiff --git a/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.c b/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.cnew file mode 100644index 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.infnew file mode 100644index 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