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


Thanks,
Chao
--------

On 11月 11 2022, at 5:12 δΈ‹εˆ, xianglai li <lixianglai@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@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.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