From nobody Sun Feb 8 18:30:14 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+95736+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+95736+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1667136560; cv=none; d=zohomail.com; s=zohoarc; b=jiWGfhmFsFgB18GrQBe3AahiJMIJ6creC0pWtA1LO8D6skscAI+/7CpMfZ4+OJ/9rAq/dU7jHQRltAqjqjXtDlpWbn/veK0dQLmICqY7Fvxh8Yw6nd+PsHNHthmQJAEADZOEtLuKULJFy/xhyeFpW7T8u0YfGAMN08RD6VLuyn0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1667136560; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=RM96JNl6iTYNaH05wopAbuxXBxx6tsAM9GzTj+mBeG4=; b=O6UKaYcis4c+easnFEA2IDcCxqkFzq2/kAqD1TrBMItG9or7xNTsZ4omtokDIqVYT3c4BkkM7KhZeJpc8nNHV+ENnAvMyMJ2o/3+Pvnf5bnV1Q1lHAPAMGx2EawKd8GLgB6IrTF3YR2pl4qBqqTIDFveB5u2bd0Y4yd+WKBPxgQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+95736+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1667136560169897.8537514496737; Sun, 30 Oct 2022 06:29:20 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 3FZuYY1788612xTM9gDKhcKQ; Sun, 30 Oct 2022 06:29:19 -0700 X-Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) by mx.groups.io with SMTP id smtpd.web09.8113.1667136546457351476 for ; Sun, 30 Oct 2022 06:29:19 -0700 X-Received: by mail-pl1-f170.google.com with SMTP id f23so8655808plr.6 for ; Sun, 30 Oct 2022 06:29:19 -0700 (PDT) X-Gm-Message-State: p4pji36yi0cRxeJ58RIvAamEx1787277AA= X-Google-Smtp-Source: AMsMyM6I1zae/8/yFoJebPVzTa2L5gia3BNvzXguoUwoerq9ACypo49k8e9KjVVfqGjj9OXp1xAC3A== X-Received: by 2002:a17:902:d409:b0:186:af8d:4029 with SMTP id b9-20020a170902d40900b00186af8d4029mr9162671ple.78.1667136558514; Sun, 30 Oct 2022 06:29:18 -0700 (PDT) X-Received: from localhost.localdomain ([49.206.12.236]) by smtp.gmail.com with ESMTPSA id r10-20020aa79eca000000b0056b6a22d6c9sm2612330pfq.212.2022.10.30.06.29.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Oct 2022 06:29:18 -0700 (PDT) From: "Sunil V L" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Brijesh Singh , Erdem Aktas , James Bottomley , Min Xu , Tom Lendacky , Daniel Schaefer , Abner Chang Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V5 10/30] OvmfPkg/Sec: Add RISC-V support Date: Sun, 30 Oct 2022 18:58:22 +0530 Message-Id: <20221030132842.54077-11-sunilvl@ventanamicro.com> In-Reply-To: <20221030132842.54077-1-sunilvl@ventanamicro.com> References: <20221030132842.54077-1-sunilvl@ventanamicro.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,sunilvl@ventanamicro.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1667136559; bh=gN2V6B0CoR4lPti/O/gawVaYDr/2hkIm0EL3joSc+cQ=; h=Cc:Date:From:Reply-To:Subject:To; b=duj72VMuX1xTtsYHE9DUD76nxqWl5enG09jWo7NfyoKu5cR3AembV79+Pm5e3mMURJD +vYvYLiXkMFjUeZGtDmkWrILa8pMR6w1E7aSLX8gdRf34LbHe5MTDrN07ng5GDJAKN40A mb4Fz/KfWc7XyncFzSUJLNdX1nOOKiKXJkk= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1667136562100100002 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4076 Add the SEC module for RISC-V. EDK2 is launched as the payload for machine mode firmware in RISC-V. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Min Xu Cc: Tom Lendacky Cc: Daniel Schaefer Cc: Abner Chang Signed-off-by: Sunil V L Acked-by: Abner Chang --- OvmfPkg/Sec/SecMain.inf | 16 +- OvmfPkg/Sec/RiscV64/SecMain.h | 64 +++ OvmfPkg/Sec/RiscV64/SecMain.c | 573 ++++++++++++++++++++ OvmfPkg/Sec/RiscV64/SecEntry.S | 21 + 4 files changed, 673 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf index a014bcb4cf1a..96fcc464c0d5 100644 --- a/OvmfPkg/Sec/SecMain.inf +++ b/OvmfPkg/Sec/SecMain.inf @@ -18,7 +18,7 @@ [Defines] # # The following information is for reference only and not required by the = build tools. # -# VALID_ARCHITECTURES =3D IA32 X64 EBC +# VALID_ARCHITECTURES =3D IA32 X64 EBC RISCV64 # =20 [Sources.IA32, Sources.X64] @@ -34,6 +34,13 @@ [Sources.IA32] [Sources.X64] X64/SecEntry.nasm =20 +[Sources.RISCV64] + SecMainCommon.c + SecMainCommon.h + RiscV64/SecEntry.S + RiscV64/SecMain.c + RiscV64/SecMain.h + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec @@ -61,11 +68,17 @@ [LibraryClasses.IA32, LibraryClasses.X64] PeiServicesLib CcProbeLib =20 +[LibraryClasses.RISCV64] + RiscVSbiLib + [Ppis] gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED gEfiPeiMpInitLibMpDepPpiGuid gEfiPeiMpInitLibUpDepPpiGuid =20 +[Ppis.RISCV64] + gEfiTemporaryRamDonePpiGuid ## PRODUCES + [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase @@ -88,6 +101,7 @@ [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress =20 [FeaturePcd] gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/OvmfPkg/Sec/RiscV64/SecMain.h b/OvmfPkg/Sec/RiscV64/SecMain.h new file mode 100644 index 000000000000..6489104a884d --- /dev/null +++ b/OvmfPkg/Sec/RiscV64/SecMain.h @@ -0,0 +1,64 @@ +/** @file + Master header file for SecCore. + + Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SEC_MAIN_H_ +#define SEC_MAIN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SecMainCommon.h" + +/** + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param SizeOfRam Size of the temporary memory available for us= e. + @param TempRamBase Base address of temporary ram + @param BootFirmwareVolume Base address of the Boot Firmware Volume. +**/ +VOID +NORETURN +EFIAPI +SecStartup ( + IN UINTN BootHartId, + IN VOID *DeviceTreeAddress + ); + +/** + Auto-generated function that calls the library constructors for all of t= he module's + dependent libraries. This function must be called by the SEC Core once = a stack has + been established. + +**/ +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + +#endif diff --git a/OvmfPkg/Sec/RiscV64/SecMain.c b/OvmfPkg/Sec/RiscV64/SecMain.c new file mode 100644 index 000000000000..3eda37e2976f --- /dev/null +++ b/OvmfPkg/Sec/RiscV64/SecMain.c @@ -0,0 +1,573 @@ +/** @file + RISC-V SEC phase module for Qemu Virt. + + Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SecMain.h" + +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +EFI_STATUS +EFIAPI +TemporaryRamDone ( + VOID + ); + +STATIC EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi =3D { + TemporaryRamMigration +}; + +STATIC EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi =3D { + TemporaryRamDone +}; + +STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] =3D { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiTemporaryRamSupportPpiGuid, + &mTemporaryRamSupportPpi + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTemporaryRamDonePpiGuid, + &mTemporaryRamDonePpi + }, +}; + +/** Temporary RAM migration function. + + This function migrates the data from temporary RAM to permanent + memory. + + @param[in] PeiServices PEI service + @param[in] TemporaryMemoryBase Temporary memory base address + @param[in] PermanentMemoryBase Permanent memory base address + @param[in] CopySize Size to copy + +**/ +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; + EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext; + + DEBUG (( + DEBUG_INFO, + "%a: Temp Mem Base:0x%Lx, Permanent Mem Base:0x%Lx, CopySize:0x%Lx\n", + __FUNCTION__, + TemporaryMemoryBase, + PermanentMemoryBase, + (UINT64)CopySize + )); + + OldHeap =3D (VOID *)(UINTN)TemporaryMemoryBase; + NewHeap =3D (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1)); + + OldStack =3D (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1)); + NewStack =3D (VOID *)(UINTN)PermanentMemoryBase; + + CopyMem (NewHeap, OldHeap, CopySize >> 1); // Migrate Heap + CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack + + // + // Reset firmware context pointer + // + GetFirmwareContextPointer (&FirmwareContext); + FirmwareContext =3D (VOID *)FirmwareContext + (unsigned long)((UINTN)New= Stack - (UINTN)OldStack); + SetFirmwareContextPointer (FirmwareContext); + + DEBUG ((DEBUG_INFO, "%a: Firmware Context is relocated to 0x%x\n", __FUN= CTION__, FirmwareContext)); + + register UINTN a0 asm ("a0") =3D (UINTN)((UINTN)NewStack - (UINTN)OldSt= ack); + + asm volatile ("add sp, sp, a0"::"r"(a0):); + return EFI_SUCCESS; +} + +/** Temprary RAM done function. + +**/ +EFI_STATUS EFIAPI +TemporaryRamDone ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "%a: 2nd time PEI core, temporary ram done.\n", __FU= NCTION__)); + return EFI_SUCCESS; +} + +/** Return platform SEC PPI before PEI Core + + @param[in,out] ThisPpiList Pointer to retrieve EFI_PEI_PPI_DESCRIPTOR. + +**/ +STATIC EFI_STATUS +GetPlatformPrePeiCorePpiDescriptor ( + IN OUT EFI_PEI_PPI_DESCRIPTOR **ThisPpiList + ) +{ + *ThisPpiList =3D mPrivateDispatchTable; + return EFI_SUCCESS; +} + +/** + Locates the main boot firmware volume. + + @param[in,out] BootFv On input, the base of the BootFv + On output, the decompressed main firmware volume + + @retval EFI_SUCCESS The main firmware volume was located and decompre= ssed + @retval EFI_NOT_FOUND The main firmware volume was not found + +**/ +EFI_STATUS +FindMainFv ( + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv + ) +{ + EFI_FIRMWARE_VOLUME_HEADER *Fv; + UINTN Distance; + + ASSERT (((UINTN)*BootFv & EFI_PAGE_MASK) =3D=3D 0); + + Fv =3D *BootFv; + Distance =3D (UINTN)(*BootFv)->FvLength; + do { + Fv =3D (EFI_FIRMWARE_VOLUME_HEADER *)((UINT8 *)Fv + EFI_PAGE_SI= ZE); + Distance +=3D EFI_PAGE_SIZE; + if (Distance > SIZE_32MB) { + return EFI_NOT_FOUND; + } + + if (Fv->Signature !=3D EFI_FVH_SIGNATURE) { + continue; + } + + if ((UINTN)Fv->FvLength < Distance) { + continue; + } + + *BootFv =3D Fv; + return EFI_SUCCESS; + } while (TRUE); +} + +/** + Locates the compressed main firmware volume and decompresses it. + + @param[in,out] Fv On input, the firmware volume to search + On output, the decompressed BOOT/PEI FV + + @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 +DecompressMemFvs ( + IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv + ) +{ + EFI_STATUS Status; + EFI_GUID_DEFINED_SECTION *Section; + UINT32 OutputBufferSize; + UINT32 ScratchBufferSize; + UINT16 SectionAttribute; + UINT32 AuthenticationStatus; + VOID *OutputBuffer; + VOID *ScratchBuffer; + EFI_COMMON_SECTION_HEADER *FvSection; + EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv; + EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv; + UINT32 FvHeaderSize; + UINT32 FvSectionSize; + + FvSection =3D (EFI_COMMON_SECTION_HEADER *)NULL; + + Status =3D FindFfsFileAndSection ( + *Fv, + EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, + EFI_SECTION_GUID_DEFINED, + (EFI_COMMON_SECTION_HEADER **)&Section + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unable to find GUID defined section\n")); + return Status; + } + + Status =3D ExtractGuidedSectionGetInfo ( + Section, + &OutputBufferSize, + &ScratchBufferSize, + &SectionAttribute + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unable to GetInfo for GUIDed section\n")); + return Status; + } + + OutputBuffer =3D (VOID *)((UINT8 *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase= ) + SIZE_1MB); + ScratchBuffer =3D ALIGN_POINTER ((UINT8 *)OutputBuffer + OutputBufferSiz= e, SIZE_1MB); + + Status =3D ExtractGuidedSectionDecode ( + Section, + &OutputBuffer, + ScratchBuffer, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Error during GUID section decode\n")); + return Status; + } + + Status =3D FindFfsSectionInstance ( + OutputBuffer, + OutputBufferSize, + EFI_SECTION_FIRMWARE_VOLUME_IMAGE, + 0, + &FvSection + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unable to find PEI FV section\n")); + return Status; + } + + ASSERT ( + SECTION_SIZE (FvSection) =3D=3D + (PcdGet32 (PcdOvmfPeiMemFvSize) + sizeof (*FvSection)) + ); + ASSERT (FvSection->Type =3D=3D EFI_SECTION_FIRMWARE_VOLUME_IMAGE); + + PeiMemFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfPeiMe= mFvBase); + CopyMem (PeiMemFv, (VOID *)(FvSection + 1), PcdGet32 (PcdOvmfPeiMemFvSiz= e)); + + if (PeiMemFv->Signature !=3D EFI_FVH_SIGNATURE) { + DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signa= ture\n", PeiMemFv)); + CpuDeadLoop (); + return EFI_VOLUME_CORRUPTED; + } + + Status =3D FindFfsSectionInstance ( + OutputBuffer, + OutputBufferSize, + EFI_SECTION_FIRMWARE_VOLUME_IMAGE, + 1, + &FvSection + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unable to find DXE FV section\n")); + return Status; + } + + ASSERT (FvSection->Type =3D=3D EFI_SECTION_FIRMWARE_VOLUME_IMAGE); + + if (IS_SECTION2 (FvSection)) { + FvSectionSize =3D SECTION2_SIZE (FvSection); + FvHeaderSize =3D sizeof (EFI_COMMON_SECTION_HEADER2); + } else { + FvSectionSize =3D SECTION_SIZE (FvSection); + FvHeaderSize =3D sizeof (EFI_COMMON_SECTION_HEADER); + } + + ASSERT (FvSectionSize =3D=3D (PcdGet32 (PcdOvmfDxeMemFvSize) + FvHeaderS= ize)); + + DxeMemFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfDxeMe= mFvBase); + CopyMem (DxeMemFv, (VOID *)((UINTN)FvSection + FvHeaderSize), PcdGet32 (= PcdOvmfDxeMemFvSize)); + + if (DxeMemFv->Signature !=3D EFI_FVH_SIGNATURE) { + DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signa= ture\n", DxeMemFv)); + CpuDeadLoop (); + return EFI_VOLUME_CORRUPTED; + } + + *Fv =3D PeiMemFv; + return EFI_SUCCESS; +} + +/** + Locates the PEI Core entry point address + + @param[in,out] 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 + +**/ +VOID +FindPeiCoreImageBase ( + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv, + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + ) +{ + *PeiCoreImageBase =3D 0; + + FindMainFv (BootFv); + + DecompressMemFvs (BootFv); + + FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase); +} + +/** + Find core image base. + +**/ +EFI_STATUS +FindImageBase ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + *SecCoreImageBase =3D 0; + + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)BootFirmwareVolumeP= tr; + EndOfFirmwareVolume =3D CurrentAddress + BootFirmwareVolumePtr->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile =3D CurrentAddress + BootFirmwareVolumePtr->HeaderLength;= ; ) { + CurrentAddress =3D (EndOfFile + 7) & 0xfffffffffffffff8ULL; + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + File =3D (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress; + Size =3D FFS_FILE_SIZE (File); + if (Size < sizeof (*File)) { + return EFI_NOT_FOUND; + } + + EndOfFile =3D CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + // + // Look for SEC Core + // + if (File->Type !=3D EFI_FV_FILETYPE_SECURITY_CORE) { + continue; + } + + // + // Loop through the FFS file sections within the FFS file + // + EndOfSection =3D (EFI_PHYSICAL_ADDRESS)(UINTN)(File + 1); + for ( ; ;) { + CurrentAddress =3D (EndOfSection + 3) & 0xfffffffffffffffcULL; + Section =3D (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddres= s; + + Size =3D SECTION_SIZE (Section); + if (Size < sizeof (*Section)) { + return EFI_NOT_FOUND; + } + + EndOfSection =3D CurrentAddress + Size; + if (EndOfSection > EndOfFile) { + return EFI_NOT_FOUND; + } + + // + // Look for executable sections + // + if ((Section->Type =3D=3D EFI_SECTION_PE32) || (Section->Type =3D=3D= EFI_SECTION_TE)) { + if (File->Type =3D=3D EFI_FV_FILETYPE_SECURITY_CORE) { + *SecCoreImageBase =3D (PHYSICAL_ADDRESS)(UINTN)(Section + 1); + } + + break; + } + } + + // + // SEC Core image found + // + if (*SecCoreImageBase !=3D 0) { + return EFI_SUCCESS; + } + } +} + +/* + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug information. It will report the= m 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 SecCoreImageBase; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + // + // Find SEC Core and PEI Core image base + // + Status =3D FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase); + ASSERT_EFI_ERROR (Status); + + FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase); + + ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + // + // Report SEC Core debug information when remote debug is enabled + // + ImageContext.ImageAddress =3D SecCoreImageBase; + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)= ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageB= ase; + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)= ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status =3D PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (= VOID **)PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint =3D 0; + } + + return; +} + +/** + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + + @param[in] BootHartId Hardware thread ID of boot hart. + @param[in] DeviceTreeAddress Pointer to Device Tree (DTB) +**/ +VOID +NORETURN +EFIAPI +SecStartup ( + IN UINTN BootHartId, + IN VOID *DeviceTreeAddress + ) +{ + EFI_RISCV_FIRMWARE_CONTEXT FirmwareContext; + EFI_FIRMWARE_VOLUME_HEADER *BootFv; + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + EFI_SEC_PEI_HAND_OFF SecCoreData; + EFI_STATUS Status; + + // + // Report Status Code to indicate entering SEC core + // + DEBUG (( + DEBUG_INFO, + "%a() BootHartId: 0x%x, DeviceTreeAddress=3D0x%x\n", + __FUNCTION__, + BootHartId, + DeviceTreeAddress + )); + + // + // Process all libraries constructor function linked to SecCore. + // + ProcessLibraryConstructorList (); + + BootFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)FixedPcdGet32 (PcdOvmfFdBaseAdd= ress); + + ASSERT (BootFv !=3D NULL); + SecCoreData.DataSize =3D (UINT16)sizeof (EFI_SEC_PEI_HAND_= OFF); + SecCoreData.BootFirmwareVolumeBase =3D BootFv; + SecCoreData.BootFirmwareVolumeSize =3D (UINTN)BootFv->FvLength; + SecCoreData.TemporaryRamBase =3D (VOID *)(UINT64)FixedPcdGet32 (Pc= dOvmfSecPeiTempRamBase); + SecCoreData.TemporaryRamSize =3D (UINTN)FixedPcdGet32 (PcdOvmfSecP= eiTempRamSize); + SecCoreData.PeiTemporaryRamBase =3D SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize =3D SecCoreData.TemporaryRamSize >> 1; + SecCoreData.StackBase =3D (UINT8 *)SecCoreData.TemporaryRam= Base + (SecCoreData.TemporaryRamSize >> 1); + SecCoreData.StackSize =3D SecCoreData.TemporaryRamSize >> 1; + + DEBUG (( + DEBUG_INFO, + "%a() BFV Base: 0x%x, BFV Size: 0x%x, TempRAM Base: 0x%x, TempRAM Size= : 0x%x, PeiTempRamBase: 0x%x, PeiTempRamSize: 0x%x, StackBase: 0x%x, StackS= ize: 0x%x\n", + __FUNCTION__, + SecCoreData.BootFirmwareVolumeBase, + SecCoreData.BootFirmwareVolumeSize, + SecCoreData.TemporaryRamBase, + SecCoreData.TemporaryRamSize, + SecCoreData.PeiTemporaryRamBase, + SecCoreData.PeiTemporaryRamSize, + SecCoreData.StackBase, + SecCoreData.StackSize + )); + + FindAndReportEntryPoints ( + &BootFv, + &PeiCoreEntryPoint + ); + if (PeiCoreEntryPoint =3D=3D NULL) { + CpuDeadLoop (); + } + + SecCoreData.BootFirmwareVolumeBase =3D BootFv; + SecCoreData.BootFirmwareVolumeSize =3D (UINTN)BootFv->FvLength; + + Status =3D GetPlatformPrePeiCorePpiDescriptor (&PpiList); + if (EFI_ERROR (Status)) { + PpiList =3D NULL; + } + + FirmwareContext.BootHartId =3D BootHartId; + FirmwareContext.FlattenedDeviceTree =3D (UINT64)DeviceTreeAddress; + SetFirmwareContextPointer (&FirmwareContext); + + // + // Transfer the control to the PEI core + // + ASSERT (PeiCoreEntryPoint !=3D NULL); + (*PeiCoreEntryPoint)(&SecCoreData, PpiList); + + // + // Should not come here. + // + UNREACHABLE (); +} diff --git a/OvmfPkg/Sec/RiscV64/SecEntry.S b/OvmfPkg/Sec/RiscV64/SecEntry.S new file mode 100644 index 000000000000..e919a3cb0e80 --- /dev/null +++ b/OvmfPkg/Sec/RiscV64/SecEntry.S @@ -0,0 +1,21 @@ +/* + Copyright (c) 2022 Ventana Micro Systems Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + */ + +#include "SecMain.h" + +.text +.align 3 + +ASM_FUNC (_ModuleEntryPoint) + /* Use Temp memory as the stack for calling to C code */ + li a4, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + li a5, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) + + /* Use Temp memory as the stack for calling to C code */ + add sp, a4, a5 + + call SecStartup --=20 2.38.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#95736): https://edk2.groups.io/g/devel/message/95736 Mute This Topic: https://groups.io/mt/94664316/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-