From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) by mx.groups.io with SMTP id smtpd.web08.1938.1662484186426365861 for ; Tue, 06 Sep 2022 10:09:46 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@ventanamicro.com header.s=google header.b=pX/rSI/y; spf=pass (domain: ventanamicro.com, ip: 209.85.214.172, mailfrom: sunilvl@ventanamicro.com) Received: by mail-pl1-f172.google.com with SMTP id x23so11927842pll.7 for ; Tue, 06 Sep 2022 10:09:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=HgdorS8z7j1X415+VY0lEyg2iIkggHWyMHFMVPSHKPo=; b=pX/rSI/ywQHnCq30yqfin7a0I/pJ52nTu2Cc8SgMDwZuMswNfKdivdLax/pxyMpA2w A72E2BB1BNTkqGOuHHgK30Kfpp0dVBc37I9heljLI8ZyhdA3txRtH63cxqPbU5AXFxmW 4XJcTKhZJHexwJtvZ4OfdpcftXZ16w7TNwFRAnlNwUKUxqpxpUFwxwXhXhQCtw/lmec4 aOcos3fl9Tls31wKv1SucbKp0Z/plQgkrxKN8LOcE8PaBnPqVHDDKRz4wk2jbeM+79as trWwkwlzdhP9RQXdMhaR3Oo8MdA9xEdNpXtkcpo+kfaX0DPAV6a9ML0sbaAzLhcjeGo4 XXTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=HgdorS8z7j1X415+VY0lEyg2iIkggHWyMHFMVPSHKPo=; b=f6kRzpazzXFLlmOqrVgZw2GD/8ihtdQPy9C11wDmIq+mFl2PQ5kdf0QW2vG8kGdM6u QCj32JTAuJfUhGUzwCTYwqaNkmrE//SUWjXQCx6Cuwe2o90wQSJQ71nJmX581Q1DNwOx RCB6cK0RxkUP2+J3FB6kB0EriEdzUq0Ou2COk1nBexBSze5Bp68TKZKaEFPGaGeUJ7OW UTNE3sUbvZFs3n04uYY2JtyzX3mYXkQ9H8/Uonsf2xMCNY8N7cUZ/YWqhqmIWbiXIJCN lxomdyyOfZkPKYAXlyu3zWtzoc9bGL9kFS5kU8Lju+Uz65Vr61j8NbgHL11ACKlnI8st Myvg== X-Gm-Message-State: ACgBeo0r4JbiI3Jz9OtF+DwNjNHEhL3UqxsH1I6QhWkrerofpTAMsOh2 cCjSJmhQLWtODkuzkDif4vydEuYkqJHVkxIE X-Google-Smtp-Source: AA6agR5yEEn27ztlEJXtC1TCgZcIKUmBWre7z+EjDpJFkeOgSxBUw3VhsQvp+G5/jVd8mxxIKe9k7A== X-Received: by 2002:a17:902:e549:b0:174:d234:6116 with SMTP id n9-20020a170902e54900b00174d2346116mr42489790plf.131.1662484185222; Tue, 06 Sep 2022 10:09:45 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([49.206.11.92]) by smtp.gmail.com with ESMTPSA id b17-20020a170903229100b00176be258f41sm3806567plh.91.2022.09.06.10.09.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Sep 2022 10:09:44 -0700 (PDT) From: "Sunil V L" To: devel@edk2.groups.io Cc: Jian J Wang , Liming Gao , Eric Dong , Ray Ni , Rahul Kumar , Debkumar De , Catharine West , Daniel Schaefer , Abner Chang , Leif Lindholm , Ard Biesheuvel , Heinrich Schuchardt , Anup Patel , Sunil V L Subject: [RFC PATCH 12/17] UefiCpuPkg/SecCore: Add SEC startup code for RISC-V Date: Tue, 6 Sep 2022 22:38:32 +0530 Message-Id: <20220906170837.491525-13-sunilvl@ventanamicro.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220906170837.491525-1-sunilvl@ventanamicro.com> References: <20220906170837.491525-1-sunilvl@ventanamicro.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Generic RISC-V platforms will start in S-mode directly. Previous M-mode firmware like opensbi will branch to the entry point in this module. This module initializes the firmware context pointer and branches to the PEI phase. Signed-off-by: Sunil V L --- UefiCpuPkg/SecCore/RiscV64/SecEntry.S | 23 + UefiCpuPkg/SecCore/RiscV64/SecMain.c | 796 ++++++++++++++++++++++++++ UefiCpuPkg/SecCore/RiscV64/SecMain.h | 63 ++ UefiCpuPkg/SecCore/SecCoreRiscV.inf | 59 ++ 4 files changed, 941 insertions(+) create mode 100644 UefiCpuPkg/SecCore/RiscV64/SecEntry.S create mode 100644 UefiCpuPkg/SecCore/RiscV64/SecMain.c create mode 100644 UefiCpuPkg/SecCore/RiscV64/SecMain.h create mode 100644 UefiCpuPkg/SecCore/SecCoreRiscV.inf diff --git a/UefiCpuPkg/SecCore/RiscV64/SecEntry.S b/UefiCpuPkg/SecCore/Ris= cV64/SecEntry.S new file mode 100644 index 0000000000..1bd0174e27 --- /dev/null +++ b/UefiCpuPkg/SecCore/RiscV64/SecEntry.S @@ -0,0 +1,23 @@ +/*=0D + Copyright (c) 2021-2022 , Hewlett Packard Enterprise Development LP. All= rights reserved.=0D + Copyright (c) 2019 Western Digital Corporation or its affiliates.=0D + Copyright (c) 2022 Ventana Micro Systems Inc.=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D + */=0D +=0D +#include "SecMain.h"=0D +=0D +.text=0D +.align 3=0D +=0D +ASM_FUNC (_ModuleEntryPoint)=0D + /* Use Temp memory as the stack for calling to C code */=0D + li a4, FixedPcdGet32 (PcdSecPeiTempRamBase)=0D + li a5, FixedPcdGet32 (PcdSecPeiTempRamSize)=0D +=0D + /* Use Temp memory as the stack for calling to C code */=0D + add sp, a4, a5=0D +=0D + call SecStartup=0D diff --git a/UefiCpuPkg/SecCore/RiscV64/SecMain.c b/UefiCpuPkg/SecCore/Risc= V64/SecMain.c new file mode 100644 index 0000000000..d9dacce319 --- /dev/null +++ b/UefiCpuPkg/SecCore/RiscV64/SecMain.c @@ -0,0 +1,796 @@ +/** @file=0D + RISC-V SEC phase module.=0D +=0D + Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.
=0D + Copyright (c) 2021-2022, Hewlett Packard Enterprise Development LP. All = rights reserved.
=0D + Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
= =0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "SecMain.h"=0D +=0D +EFI_STATUS=0D +EFIAPI=0D +TemporaryRamMigration (=0D + IN CONST EFI_PEI_SERVICES **PeiServices,=0D + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,=0D + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,=0D + IN UINTN CopySize=0D + );=0D +=0D +EFI_STATUS=0D +EFIAPI=0D +TemporaryRamDone (=0D + VOID=0D + );=0D +=0D +STATIC EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi =3D {=0D + TemporaryRamMigration=0D +};=0D +=0D +STATIC EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi =3D {=0D + TemporaryRamDone=0D +};=0D +=0D +STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] =3D {=0D + {=0D + EFI_PEI_PPI_DESCRIPTOR_PPI,=0D + &gEfiTemporaryRamSupportPpiGuid,=0D + &mTemporaryRamSupportPpi=0D + },=0D + {=0D + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),= =0D + &gEfiTemporaryRamDonePpiGuid,=0D + &mTemporaryRamDonePpi=0D + },=0D +};=0D +=0D +/** Temporary RAM migration function.=0D +=0D + This function migrates the data from temporary RAM to permanent=0D + memory.=0D +=0D + @param[in] PeiServices PEI service=0D + @param[in] TemporaryMemoryBase Temporary memory base address=0D + @param[in] PermanentMemoryBase Permanent memory base address=0D + @param[in] CopySize Size to copy=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +TemporaryRamMigration (=0D + IN CONST EFI_PEI_SERVICES **PeiServices,=0D + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,=0D + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,=0D + IN UINTN CopySize=0D + )=0D +{=0D + VOID *OldHeap;=0D + VOID *NewHeap;=0D + VOID *OldStack;=0D + VOID *NewStack;=0D + EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;=0D +=0D + DEBUG ((DEBUG_INFO,=0D + "%a: Temp Mem Base:0x%Lx, Permanent Mem Base:0x%Lx, CopySize:0x%Lx\n",= =0D + __FUNCTION__,=0D + TemporaryMemoryBase,=0D + PermanentMemoryBase,=0D + (UINT64)CopySize=0D + ));=0D +=0D + OldHeap =3D (VOID*)(UINTN)TemporaryMemoryBase;=0D + NewHeap =3D (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));=0D +=0D + OldStack =3D (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));=0D + NewStack =3D (VOID*)(UINTN)PermanentMemoryBase;=0D +=0D + CopyMem (NewHeap, OldHeap, CopySize >> 1); // Migrate Heap=0D + CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack=0D +=0D + //=0D + // Reset firmware context pointer=0D + //=0D + GetFirmwareContextPointer (&FirmwareContext);=0D + FirmwareContext =3D (VOID *)FirmwareContext + (unsigned long)((UINTN)New= Stack - (UINTN)OldStack);=0D + SetFirmwareContextPointer (FirmwareContext);=0D +=0D + DEBUG ((DEBUG_INFO, "%a: Firmware Context is relocated to 0x%x\n", __FUN= CTION__, FirmwareContext));=0D +=0D + register UINTN a0 asm ("a0") =3D (UINTN)((UINTN)NewStack - (UINTN)OldSt= ack);=0D + asm volatile ("add sp, sp, a0"::"r"(a0):);=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/** Temprary RAM done function.=0D +=0D +**/=0D +EFI_STATUS EFIAPI TemporaryRamDone (=0D + VOID=0D + )=0D +{=0D + DEBUG ((DEBUG_INFO, "%a: 2nd time PEI core, temporary ram done.\n", __FU= NCTION__));=0D + return EFI_SUCCESS;=0D +}=0D +/** Return platform SEC PPI before PEI Core=0D +=0D + @param[in,out] ThisPpiList Pointer to retrieve EFI_PEI_PPI_DESCRIPTOR= .=0D +=0D +**/=0D +STATIC EFI_STATUS=0D +GetPlatformPrePeiCorePpiDescriptor (=0D + IN OUT EFI_PEI_PPI_DESCRIPTOR **ThisPpiList=0D +)=0D +{=0D + *ThisPpiList =3D mPrivateDispatchTable;=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Locates the main boot firmware volume.=0D +=0D + @param[in,out] BootFv On input, the base of the BootFv=0D + On output, the decompressed main firmware volume= =0D +=0D + @retval EFI_SUCCESS The main firmware volume was located and decompre= ssed=0D + @retval EFI_NOT_FOUND The main firmware volume was not found=0D +=0D +**/=0D +EFI_STATUS=0D +FindMainFv (=0D + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv=0D + )=0D +{=0D + EFI_FIRMWARE_VOLUME_HEADER *Fv;=0D + UINTN Distance;=0D +=0D + ASSERT (((UINTN)*BootFv & EFI_PAGE_MASK) =3D=3D 0);=0D +=0D + Fv =3D *BootFv;=0D + Distance =3D (UINTN)(*BootFv)->FvLength;=0D + do {=0D + Fv =3D (EFI_FIRMWARE_VOLUME_HEADER *)((UINT8 *)Fv + EFI_PAGE_SI= ZE);=0D + Distance +=3D EFI_PAGE_SIZE;=0D + if (Distance > SIZE_32MB) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + if (Fv->Signature !=3D EFI_FVH_SIGNATURE) {=0D + continue;=0D + }=0D +=0D + if ((UINTN)Fv->FvLength < Distance) {=0D + continue;=0D + }=0D +=0D + *BootFv =3D Fv;=0D + return EFI_SUCCESS;=0D + } while (TRUE);=0D +}=0D +=0D +/**=0D + Locates a section within a series of sections=0D + with the specified section type.=0D +=0D + The Instance parameter indicates which instance of the section=0D + type to return. (0 is first instance, 1 is second...)=0D +=0D + @param[in] Sections The sections to search=0D + @param[in] SizeOfSections Total size of all sections=0D + @param[in] SectionType The section type to locate=0D + @param[in] Instance The section instance number=0D + @param[out] FoundSection The FFS section if found=0D +=0D + @retval EFI_SUCCESS The file and section was found=0D + @retval EFI_NOT_FOUND The file and section was not found=0D + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted=0D +=0D +**/=0D +EFI_STATUS=0D +FindFfsSectionInstance (=0D + IN VOID *Sections,=0D + IN UINTN SizeOfSections,=0D + IN EFI_SECTION_TYPE SectionType,=0D + IN UINTN Instance,=0D + OUT EFI_COMMON_SECTION_HEADER **FoundSection=0D + )=0D +{=0D + EFI_PHYSICAL_ADDRESS CurrentAddress;=0D + UINT32 Size;=0D + EFI_PHYSICAL_ADDRESS EndOfSections;=0D + EFI_COMMON_SECTION_HEADER *Section;=0D + EFI_PHYSICAL_ADDRESS EndOfSection;=0D +=0D + //=0D + // Loop through the FFS file sections within the PEI Core FFS file=0D + //=0D + EndOfSection =3D (EFI_PHYSICAL_ADDRESS)(UINTN)Sections;=0D + EndOfSections =3D EndOfSection + SizeOfSections;=0D + for ( ; ;) {=0D + if (EndOfSection =3D=3D EndOfSections) {=0D + break;=0D + }=0D +=0D + CurrentAddress =3D (EndOfSection + 3) & ~(3ULL);=0D + if (CurrentAddress >=3D EndOfSections) {=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D +=0D + Section =3D (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;=0D +=0D + Size =3D SECTION_SIZE (Section);=0D + if (Size < sizeof (*Section)) {=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D +=0D + EndOfSection =3D CurrentAddress + Size;=0D + if (EndOfSection > EndOfSections) {=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D +=0D + //=0D + // Look for the requested section type=0D + //=0D + if (Section->Type =3D=3D SectionType) {=0D + if (Instance =3D=3D 0) {=0D + *FoundSection =3D Section;=0D + return EFI_SUCCESS;=0D + } else {=0D + Instance--;=0D + }=0D + }=0D + }=0D +=0D + return EFI_NOT_FOUND;=0D +}=0D +=0D +/**=0D + Locates a section within a series of sections=0D + with the specified section type.=0D +=0D + @param[in] Sections The sections to search=0D + @param[in] SizeOfSections Total size of all sections=0D + @param[in] SectionType The section type to locate=0D + @param[out] FoundSection The FFS section if found=0D +=0D + @retval EFI_SUCCESS The file and section was found=0D + @retval EFI_NOT_FOUND The file and section was not found=0D + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted=0D +=0D +**/=0D +EFI_STATUS=0D +FindFfsSectionInSections (=0D + IN VOID *Sections,=0D + IN UINTN SizeOfSections,=0D + IN EFI_SECTION_TYPE SectionType,=0D + OUT EFI_COMMON_SECTION_HEADER **FoundSection=0D + )=0D +{=0D + return FindFfsSectionInstance (=0D + Sections,=0D + SizeOfSections,=0D + SectionType,=0D + 0,=0D + FoundSection=0D + );=0D +}=0D +=0D +/**=0D + Locates a FFS file with the specified file type and a section=0D + within that file with the specified section type.=0D +=0D + @param[in] Fv The firmware volume to search=0D + @param[in] FileType The file type to locate=0D + @param[in] SectionType The section type to locate=0D + @param[out] FoundSection The FFS section if found=0D +=0D + @retval EFI_SUCCESS The file and section was found=0D + @retval EFI_NOT_FOUND The file and section was not found=0D + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted=0D +=0D +**/=0D +EFI_STATUS=0D +FindFfsFileAndSection (=0D + IN EFI_FIRMWARE_VOLUME_HEADER *Fv,=0D + IN EFI_FV_FILETYPE FileType,=0D + IN EFI_SECTION_TYPE SectionType,=0D + OUT EFI_COMMON_SECTION_HEADER **FoundSection=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_PHYSICAL_ADDRESS CurrentAddress;=0D + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;=0D + EFI_FFS_FILE_HEADER *File;=0D + UINT32 Size;=0D + EFI_PHYSICAL_ADDRESS EndOfFile;=0D +=0D + if (Fv->Signature !=3D EFI_FVH_SIGNATURE) {=0D + DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", F= v));=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D +=0D + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)Fv;=0D + EndOfFirmwareVolume =3D CurrentAddress + Fv->FvLength;=0D +=0D + //=0D + // Loop through the FFS files in the Boot Firmware Volume=0D + //=0D + for (EndOfFile =3D CurrentAddress + Fv->HeaderLength; ; ) {=0D + CurrentAddress =3D (EndOfFile + 7) & ~(7ULL);=0D + if (CurrentAddress > EndOfFirmwareVolume) {=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D +=0D + File =3D (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;=0D + Size =3D FFS_FILE_SIZE (File);=0D + if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D +=0D + EndOfFile =3D CurrentAddress + Size;=0D + if (EndOfFile > EndOfFirmwareVolume) {=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D +=0D + //=0D + // Look for the request file type=0D + //=0D + if (File->Type !=3D FileType) {=0D + continue;=0D + }=0D +=0D + Status =3D FindFfsSectionInSections (=0D + (VOID *)(File + 1),=0D + (UINTN)EndOfFile - (UINTN)(File + 1),=0D + SectionType,=0D + FoundSection=0D + );=0D + if (!EFI_ERROR (Status) || (Status =3D=3D EFI_VOLUME_CORRUPTED)) {=0D + return Status;=0D + }=0D + }=0D +}=0D +=0D +/**=0D + Locates the compressed main firmware volume and decompresses it.=0D +=0D + @param[in,out] Fv On input, the firmware volume to search=0D + On output, the decompressed BOOT/PEI FV=0D +=0D + @retval EFI_SUCCESS The file and section was found=0D + @retval EFI_NOT_FOUND The file and section was not found=0D + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted=0D +=0D +**/=0D +EFI_STATUS=0D +DecompressMemFvs (=0D + IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_GUID_DEFINED_SECTION *Section;=0D + UINT32 OutputBufferSize;=0D + UINT32 ScratchBufferSize;=0D + UINT16 SectionAttribute;=0D + UINT32 AuthenticationStatus;=0D + VOID *OutputBuffer;=0D + VOID *ScratchBuffer;=0D + EFI_COMMON_SECTION_HEADER *FvSection;=0D + EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv;=0D + EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv;=0D + UINT32 FvHeaderSize;=0D + UINT32 FvSectionSize;=0D +=0D + FvSection =3D (EFI_COMMON_SECTION_HEADER *)NULL;=0D +=0D + Status =3D FindFfsFileAndSection (=0D + *Fv,=0D + EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,=0D + EFI_SECTION_GUID_DEFINED,=0D + (EFI_COMMON_SECTION_HEADER **)&Section=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Unable to find GUID defined section\n"));=0D + return Status;=0D + }=0D +=0D + Status =3D ExtractGuidedSectionGetInfo (=0D + Section,=0D + &OutputBufferSize,=0D + &ScratchBufferSize,=0D + &SectionAttribute=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Unable to GetInfo for GUIDed section\n"));=0D + return Status;=0D + }=0D +=0D + OutputBuffer =3D (VOID *)((UINT8 *)(UINTN)PcdGet32 (PcdDxeMemFvBase) + = SIZE_1MB);=0D + ScratchBuffer =3D ALIGN_POINTER ((UINT8 *)OutputBuffer + OutputBufferSiz= e, SIZE_1MB);=0D +=0D + Status =3D ExtractGuidedSectionDecode (=0D + Section,=0D + &OutputBuffer,=0D + ScratchBuffer,=0D + &AuthenticationStatus=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Error during GUID section decode\n"));=0D + return Status;=0D + }=0D +=0D + Status =3D FindFfsSectionInstance (=0D + OutputBuffer,=0D + OutputBufferSize,=0D + EFI_SECTION_FIRMWARE_VOLUME_IMAGE,=0D + 0,=0D + &FvSection=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Unable to find PEI FV section\n"));=0D + return Status;=0D + }=0D +=0D + ASSERT (=0D + SECTION_SIZE (FvSection) =3D=3D=0D + (PcdGet32 (PcdPeiMemFvSize) + sizeof (*FvSection))=0D + );=0D + ASSERT (FvSection->Type =3D=3D EFI_SECTION_FIRMWARE_VOLUME_IMAGE);=0D +=0D + PeiMemFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdPeiMemFvB= ase);=0D + CopyMem (PeiMemFv, (VOID *)(FvSection + 1), PcdGet32 (PcdPeiMemFvSize));= =0D +=0D + if (PeiMemFv->Signature !=3D EFI_FVH_SIGNATURE) {=0D + DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signa= ture\n", PeiMemFv));=0D + CpuDeadLoop ();=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D +=0D + Status =3D FindFfsSectionInstance (=0D + OutputBuffer,=0D + OutputBufferSize,=0D + EFI_SECTION_FIRMWARE_VOLUME_IMAGE,=0D + 1,=0D + &FvSection=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Unable to find DXE FV section\n"));=0D + return Status;=0D + }=0D +=0D + ASSERT (FvSection->Type =3D=3D EFI_SECTION_FIRMWARE_VOLUME_IMAGE);=0D +=0D + if (IS_SECTION2 (FvSection)) {=0D + FvSectionSize =3D SECTION2_SIZE (FvSection);=0D + FvHeaderSize =3D sizeof (EFI_COMMON_SECTION_HEADER2);=0D + } else {=0D + FvSectionSize =3D SECTION_SIZE (FvSection);=0D + FvHeaderSize =3D sizeof (EFI_COMMON_SECTION_HEADER);=0D + }=0D +=0D + ASSERT (FvSectionSize =3D=3D (PcdGet32 (PcdDxeMemFvSize) + FvHeaderSize)= );=0D +=0D + DxeMemFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdDxeMemFvB= ase);=0D + CopyMem (DxeMemFv, (VOID *)((UINTN)FvSection + FvHeaderSize), PcdGet32 (= PcdDxeMemFvSize));=0D +=0D + if (DxeMemFv->Signature !=3D EFI_FVH_SIGNATURE) {=0D + DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signa= ture\n", DxeMemFv));=0D + CpuDeadLoop ();=0D + return EFI_VOLUME_CORRUPTED;=0D + }=0D + *Fv =3D PeiMemFv;=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Locates the PEI Core entry point address=0D +=0D + @param[in] Fv The firmware volume to search=0D + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image=0D +=0D + @retval EFI_SUCCESS The file and section was found=0D + @retval EFI_NOT_FOUND The file and section was not found=0D + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted=0D +=0D +**/=0D +EFI_STATUS=0D +FindPeiCoreImageBaseInFv (=0D + IN EFI_FIRMWARE_VOLUME_HEADER *Fv,=0D + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_COMMON_SECTION_HEADER *Section;=0D +=0D + Status =3D FindFfsFileAndSection (=0D + Fv,=0D + EFI_FV_FILETYPE_PEI_CORE,=0D + EFI_SECTION_PE32,=0D + &Section=0D + );=0D + if (EFI_ERROR (Status)) {=0D + Status =3D FindFfsFileAndSection (=0D + Fv,=0D + EFI_FV_FILETYPE_PEI_CORE,=0D + EFI_SECTION_TE,=0D + &Section=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));=0D + return Status;=0D + }=0D + }=0D +=0D + *PeiCoreImageBase =3D (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Locates the PEI Core entry point address=0D +=0D + @param[in,out] Fv The firmware volume to search=0D + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image= =0D +=0D + @retval EFI_SUCCESS The file and section was found=0D + @retval EFI_NOT_FOUND The file and section was not found=0D + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted=0D +=0D +**/=0D +VOID=0D +FindPeiCoreImageBase (=0D + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,=0D + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase=0D + )=0D +{=0D +=0D + *PeiCoreImageBase =3D 0;=0D +=0D + FindMainFv (BootFv);=0D +=0D + DecompressMemFvs (BootFv);=0D +=0D + FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);=0D +}=0D +=0D +/**=0D + Find core image base.=0D +=0D +**/=0D +EFI_STATUS=0D +FindImageBase (=0D + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,=0D + OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase=0D + )=0D +{=0D + EFI_PHYSICAL_ADDRESS CurrentAddress;=0D + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;=0D + EFI_FFS_FILE_HEADER *File;=0D + UINT32 Size;=0D + EFI_PHYSICAL_ADDRESS EndOfFile;=0D + EFI_COMMON_SECTION_HEADER *Section;=0D + EFI_PHYSICAL_ADDRESS EndOfSection;=0D +=0D + *SecCoreImageBase =3D 0;=0D +=0D + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)BootFirmwareVolumeP= tr;=0D + EndOfFirmwareVolume =3D CurrentAddress + BootFirmwareVolumePtr->FvLength= ;=0D +=0D + //=0D + // Loop through the FFS files in the Boot Firmware Volume=0D + //=0D + for (EndOfFile =3D CurrentAddress + BootFirmwareVolumePtr->HeaderLength;= ; ) {=0D + CurrentAddress =3D (EndOfFile + 7) & 0xfffffffffffffff8ULL;=0D + if (CurrentAddress > EndOfFirmwareVolume) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + File =3D (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;=0D + Size =3D FFS_FILE_SIZE (File);=0D + if (Size < sizeof (*File)) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + EndOfFile =3D CurrentAddress + Size;=0D + if (EndOfFile > EndOfFirmwareVolume) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + //=0D + // Look for SEC Core=0D + //=0D + if (File->Type !=3D EFI_FV_FILETYPE_SECURITY_CORE) {=0D + continue;=0D + }=0D +=0D + //=0D + // Loop through the FFS file sections within the FFS file=0D + //=0D + EndOfSection =3D (EFI_PHYSICAL_ADDRESS)(UINTN)(File + 1);=0D + for ( ; ;) {=0D + CurrentAddress =3D (EndOfSection + 3) & 0xfffffffffffffffcULL;=0D + Section =3D (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddres= s;=0D +=0D + Size =3D SECTION_SIZE (Section);=0D + if (Size < sizeof (*Section)) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + EndOfSection =3D CurrentAddress + Size;=0D + if (EndOfSection > EndOfFile) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + //=0D + // Look for executable sections=0D + //=0D + if ((Section->Type =3D=3D EFI_SECTION_PE32) || (Section->Type =3D=3D= EFI_SECTION_TE)) {=0D + if (File->Type =3D=3D EFI_FV_FILETYPE_SECURITY_CORE) {=0D + *SecCoreImageBase =3D (PHYSICAL_ADDRESS)(UINTN)(Section + 1);=0D + }=0D +=0D + break;=0D + }=0D + }=0D +=0D + //=0D + // SEC Core image found=0D + //=0D + if (*SecCoreImageBase !=3D 0) {=0D + return EFI_SUCCESS;=0D + }=0D + }=0D +}=0D +=0D +/*=0D + Find and return Pei Core entry point.=0D +=0D + It also find SEC and PEI Core file debug information. It will report the= m if=0D + remote debug is enabled.=0D +=0D +**/=0D +VOID=0D +FindAndReportEntryPoints (=0D + IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,=0D + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_PHYSICAL_ADDRESS SecCoreImageBase;=0D + EFI_PHYSICAL_ADDRESS PeiCoreImageBase;=0D + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;=0D +=0D + //=0D + // Find SEC Core and PEI Core image base=0D + //=0D + Status =3D FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);=0D +=0D + ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));= =0D + //=0D + // Report SEC Core debug information when remote debug is enabled=0D + //=0D + ImageContext.ImageAddress =3D SecCoreImageBase;=0D + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)= ImageContext.ImageAddress);=0D + PeCoffLoaderRelocateImageExtraAction (&ImageContext);=0D +=0D + //=0D + // Report PEI Core debug information when remote debug is enabled=0D + //=0D + ImageContext.ImageAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageB= ase;=0D + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)= ImageContext.ImageAddress);=0D + PeCoffLoaderRelocateImageExtraAction (&ImageContext);=0D +=0D + //=0D + // Find PEI Core entry point=0D + //=0D + Status =3D PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (= VOID **)PeiCoreEntryPoint);=0D + if (EFI_ERROR (Status)) {=0D + *PeiCoreEntryPoint =3D 0;=0D + }=0D +=0D + return;=0D +}=0D +=0D +/**=0D +=0D + Entry point to the C language phase of SEC. After the SEC assembly=0D + code has initialized some temporary memory and set up the stack,=0D + the control is transferred to this function.=0D +=0D +=0D + @param[in] BootHartId Hardware thread ID of boot hart.=0D + @param[in] DeviceTreeAddress Pointer to Device Tree (DTB)=0D +**/=0D +VOID=0D +NORETURN=0D +EFIAPI=0D +SecStartup (=0D + IN UINTN BootHartId,=0D + IN VOID *DeviceTreeAddress=0D + )=0D +{=0D + EFI_RISCV_FIRMWARE_CONTEXT FirmwareContext;=0D + EFI_FIRMWARE_VOLUME_HEADER *BootFv;=0D + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;=0D + EFI_PEI_PPI_DESCRIPTOR *PpiList;=0D + EFI_SEC_PEI_HAND_OFF SecCoreData;=0D + EFI_STATUS Status;=0D +=0D + //=0D + // Report Status Code to indicate entering SEC core=0D + //=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "%a() BootHartId: 0x%x, DeviceTreeAddress=3D0x%x\n",=0D + __FUNCTION__,=0D + BootHartId,=0D + DeviceTreeAddress=0D + ));=0D +=0D + //=0D + // Process all libraries constructor function linked to SecCore.=0D + //=0D + ProcessLibraryConstructorList ();=0D +=0D + BootFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)FixedPcdGet32 (PcdSecMemFvBase)= ;=0D +=0D + ASSERT(BootFv !=3D NULL);=0D + SecCoreData.DataSize =3D (UINT16)sizeof (EFI_SEC_PEI_HAND_= OFF);=0D + SecCoreData.BootFirmwareVolumeBase =3D BootFv;=0D + SecCoreData.BootFirmwareVolumeSize =3D (UINTN)FixedPcdGet32 (PcdSecMemFv= Size);=0D + SecCoreData.TemporaryRamBase =3D (VOID *)(UINT64)FixedPcdGet32 (Pc= dSecPeiTempRamBase);=0D + SecCoreData.TemporaryRamSize =3D (UINTN)FixedPcdGet32 (PcdSecPeiTe= mpRamSize);=0D + SecCoreData.PeiTemporaryRamBase =3D SecCoreData.TemporaryRamBase;=0D + SecCoreData.PeiTemporaryRamSize =3D SecCoreData.TemporaryRamSize >> 1= ;=0D + SecCoreData.StackBase =3D (UINT8 *)SecCoreData.TemporaryRam= Base + (SecCoreData.TemporaryRamSize >> 1);=0D + SecCoreData.StackSize =3D SecCoreData.TemporaryRamSize >> 1= ;=0D +=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "%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",=0D + __FUNCTION__,=0D + SecCoreData.BootFirmwareVolumeBase,=0D + SecCoreData.BootFirmwareVolumeSize,=0D + SecCoreData.TemporaryRamBase,=0D + SecCoreData.TemporaryRamSize,=0D + SecCoreData.PeiTemporaryRamBase,=0D + SecCoreData.PeiTemporaryRamSize,=0D + SecCoreData.StackBase,=0D + SecCoreData.StackSize=0D + ));=0D +=0D + FindAndReportEntryPoints (=0D + &BootFv,=0D + &PeiCoreEntryPoint=0D + );=0D + if (PeiCoreEntryPoint =3D=3D NULL) {=0D + CpuDeadLoop ();=0D + }=0D +=0D + SecCoreData.BootFirmwareVolumeBase =3D BootFv;=0D + SecCoreData.BootFirmwareVolumeSize =3D (UINTN) BootFv->FvLength;=0D +=0D + Status =3D GetPlatformPrePeiCorePpiDescriptor (&PpiList);=0D + if (EFI_ERROR (Status)) {=0D + PpiList =3D NULL;=0D + }=0D +=0D + FirmwareContext.BootHartId =3D BootHartId;=0D + FirmwareContext.FlattenedDeviceTree =3D (UINT64)DeviceTreeAddress;=0D + SetFirmwareContextPointer (&FirmwareContext);=0D +=0D + //=0D + // Transfer the control to the PEI core=0D + //=0D + ASSERT (PeiCoreEntryPoint !=3D NULL);=0D + (*PeiCoreEntryPoint)(&SecCoreData, PpiList);=0D +=0D + //=0D + // Should not come here.=0D + //=0D + UNREACHABLE ();=0D +}=0D diff --git a/UefiCpuPkg/SecCore/RiscV64/SecMain.h b/UefiCpuPkg/SecCore/Risc= V64/SecMain.h new file mode 100644 index 0000000000..eeb368de02 --- /dev/null +++ b/UefiCpuPkg/SecCore/RiscV64/SecMain.h @@ -0,0 +1,63 @@ +/** @file=0D + Master header file for SecCore.=0D +=0D + Copyright (c) 2019-2022, Hewlett Packard Enterprise Development LP. All = rights reserved.
=0D + Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
= =0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef _SEC_MAIN_H_=0D +#define _SEC_MAIN_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + Entry point to the C language phase of SEC. After the SEC assembly=0D + code has initialized some temporary memory and set up the stack,=0D + the control is transferred to this function.=0D +=0D + @param SizeOfRam Size of the temporary memory available for us= e.=0D + @param TempRamBase Base address of temporary ram=0D + @param BootFirmwareVolume Base address of the Boot Firmware Volume.=0D +**/=0D +VOID=0D +NORETURN=0D +EFIAPI=0D +SecStartup (=0D + IN UINTN BootHartId,=0D + IN VOID *DeviceTreeAddress=0D + );=0D +=0D +/**=0D + Auto-generated function that calls the library constructors for all of t= he module's=0D + dependent libraries. This function must be called by the SEC Core once = a stack has=0D + been established.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +ProcessLibraryConstructorList (=0D + VOID=0D + );=0D +=0D +#endif=0D diff --git a/UefiCpuPkg/SecCore/SecCoreRiscV.inf b/UefiCpuPkg/SecCore/SecCo= reRiscV.inf new file mode 100644 index 0000000000..8ba6400f53 --- /dev/null +++ b/UefiCpuPkg/SecCore/SecCoreRiscV.inf @@ -0,0 +1,59 @@ +## @file=0D +# RISC-V SEC module which boots in S-mode.=0D +#=0D +# Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All righ= ts reserved.
=0D +# Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
= =0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x0001001b=0D + BASE_NAME =3D SecMain=0D + FILE_GUID =3D 42C30D8E-BFAD-4E77-9041-E7DAAE88DF7A= =0D + MODULE_TYPE =3D SEC=0D + VERSION_STRING =3D 1.0=0D + ENTRY_POINT =3D SecMain=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D RISCV64=0D +#=0D +=0D +[Sources]=0D + RiscV64/SecEntry.S=0D + RiscV64/SecMain.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + MdeModulePkg/MdeModulePkg.dec=0D + UefiCpuPkg/UefiCpuPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseMemoryLib=0D + DebugLib=0D + PlatformSecLib=0D + PcdLib=0D + CpuLib=0D + PeCoffGetEntryPointLib=0D + PeCoffExtraActionLib=0D + RiscVSbiLib=0D +=0D +[Ppis]=0D + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED=0D + gEfiTemporaryRamDonePpiGuid # PPI ALWAYS_PRODUCED=0D +=0D +[Pcd]=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdSecMemFvBase=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdSecMemFvSize=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiMemFvBase=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiMemFvSize=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeMemFvBase=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeMemFvSize=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdSecPeiTempRamBase=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdSecPeiTempRamSize=0D +=0D +[UserExtensions.TianoCore."ExtraFiles"]=0D + SecCoreExtra.uni=0D --=20 2.25.1