From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by mx.groups.io with SMTP id smtpd.web10.2662.1641618761687548130 for ; Fri, 07 Jan 2022 21:12:42 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@hpe.com header.s=pps0720 header.b=JLhLGEOC; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: hpe.com, ip: 148.163.143.35, mailfrom: prvs=000704d8ca=abner.chang@hpe.com) Received: from pps.filterd (m0134423.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 2081WPKD003576 for ; Sat, 8 Jan 2022 05:12:40 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pps0720; bh=a46mNIWf4KPLPlPbG+W9obzZM96O/s905jUvQmML0iw=; b=JLhLGEOCRwHZdHHrGy/aRtjhf/eaB84Sd79XcTsE6nHOZUHn6UgWZhmJ5Z/MpcBZnP8r 2WdUefWfmnxi/uo8wRHhvH5mtNr5WnbeDl3gcKvk0Nflyb4pmvZmpykZ7A5JgS2AjPiR 8sn5pqOLLpvI7c/uQ3AuSw9WODc4DQZEk460W6Nu3Uol/S6CR8a1zD+8oCajSE1AQyvh vIlKpLD9OBE0fzkG0j0mv/ZaEK/Rc8/kXB/znCpIU2qR8uPPG1mbtAxDDks0J/FkMibm Q6VDqZ1LWj2V1jpRcDlq/pVPCOHjDp+dUnAY0nBZHbJPmXIDxOZdbu7QizmdrR2X58cA ng== Received: from g2t2352.austin.hpe.com (g2t2352.austin.hpe.com [15.233.44.25]) by mx0b-002e3701.pphosted.com (PPS) with ESMTPS id 3df04bh2jf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Sat, 08 Jan 2022 05:12:40 +0000 Received: from g2t2360.austin.hpecorp.net (g2t2360.austin.hpecorp.net [16.196.225.135]) by g2t2352.austin.hpe.com (Postfix) with ESMTP id 1E8349B for ; Sat, 8 Jan 2022 05:12:40 +0000 (UTC) Received: from UB16Abner.asiapacific.hpqcorp.net (ub16abner.asiapacific.hpqcorp.net [15.119.209.229]) by g2t2360.austin.hpecorp.net (Postfix) with ESMTP id 678C039; Sat, 8 Jan 2022 05:12:39 +0000 (UTC) From: "Abner Chang" To: devel@edk2.groups.io Cc: abner.chang@hpe.com Subject: [PATCH 19/79] PlatformPkg/SecMain: RISC-V SecMain module. Date: Sat, 8 Jan 2022 12:10:39 +0800 Message-Id: <20220108041121.16005-18-abner.chang@hpe.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220108041121.16005-1-abner.chang@hpe.com> References: <20220108041121.16005-1-abner.chang@hpe.com> MIME-Version: 1.0 X-Proofpoint-GUID: eZgg7DQ8r4W1bgVqZX5IN6A-qPZvO33Z X-Proofpoint-ORIG-GUID: eZgg7DQ8r4W1bgVqZX5IN6A-qPZvO33Z X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-08_01,2022-01-07_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 mlxlogscore=999 spamscore=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 adultscore=0 impostorscore=0 suspectscore=0 priorityscore=1501 mlxscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2201080036 Content-Transfer-Encoding: quoted-printable (This is migrated from edk2-platforms:Platform/RISC-V) SecMain module for RISC-V platform. This was cloned from OpenSBI fw_base.S (RiscVPkg/Library/RiscVOpensbiLib/opensbi/firmware/) and revised to edk2 framework. Signed-off-by: Abner Chang Co-authored-by: Daniel Schaefer Co-authored-by: Gilbert Chen Reviewed-by: Leif Lindholm Cc: Leif Lindholm Cc: Gilbert Chen --- .../PlatformPkg/Universal/Sec/SecMain.inf | 77 ++ .../PlatformPkg/Universal/Sec/SecMain.h | 57 ++ .../PlatformPkg/Universal/Sec/SecMain.c | 733 ++++++++++++++++++ .../Universal/Sec/Riscv64/SecEntry.S | 532 +++++++++++++ 4 files changed, 1399 insertions(+) create mode 100644 Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf create mode 100644 Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.h create mode 100644 Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c create mode 100644 Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEn= try.S diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf b/Platfo= rm/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf new file mode 100644 index 0000000000..89bcb039a6 --- /dev/null +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf @@ -0,0 +1,77 @@ +## @file=0D +# RISC-V SEC module.=0D +#=0D +# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All righ= ts 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 743467B0-849F-4ACE-9BFB-515CE6206388= =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 + SecMain.c=0D +=0D +[Sources.RISCV64]=0D + Riscv64/SecEntry.S=0D +=0D +[Packages]=0D + MdeModulePkg/MdeModulePkg.dec=0D + MdePkg/MdePkg.dec=0D + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec=0D + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + DebugAgentLib=0D + DebugLib=0D + ExtractGuidedSectionLib=0D + IoLib=0D + PcdLib=0D + PeCoffLib=0D + PeCoffGetEntryPointLib=0D + PeCoffExtraActionLib=0D + PrintLib=0D + RiscVCpuLib=0D + RiscVOpensbiLib=0D + RiscVOpensbiPlatformLib=0D + RiscVEdk2SbiLib=0D +=0D +[Ppis]=0D + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED=0D + gEfiTemporaryRamDonePpiGuid # PPI ALWAYS_PRODUCED=0D +=0D +[FixedPcd]=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize=0D +=0D +[Pcd]=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartNumber=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize=0D + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPeiCorePrivilegeMode=0D +=0D +[BuildOptions]=0D + GCC:*_*_*_PP_FLAGS =3D -D__ASSEMBLY__=0D +=0D +=0D diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.h b/Platform= /RISC-V/PlatformPkg/Universal/Sec/SecMain.h new file mode 100644 index 0000000000..94ea46263c --- /dev/null +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.h @@ -0,0 +1,57 @@ +/** @file=0D + RISC-V SEC phase module definitions..=0D +=0D + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef SECMAIN_H_=0D +#define SECMAIN_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 +=0D +VOID=0D +SecMachineModeTrapHandler (=0D + IN VOID=0D + );=0D +=0D +VOID=0D +EFIAPI=0D +SecStartupPhase2 (=0D + IN VOID *Context=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 +EFI_STATUS=0D +EFIAPI=0D +TemporaryRamDone (=0D + VOID=0D + );=0D +=0D +#endif // _SECMAIN_H_=0D diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c b/Platform= /RISC-V/PlatformPkg/Universal/Sec/SecMain.c new file mode 100644 index 0000000000..877777bfa1 --- /dev/null +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c @@ -0,0 +1,733 @@ +/** @file=0D + RISC-V SEC phase module.=0D +=0D + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All right= s reserved.
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include // Reference to header file in opensbi=0D +#include // Reference to header file in opensbi=0D +#include // Reference to header file in opensbi=0D +#include // Reference to header file in opensbi=0D +#include // Reference to header file in opensbi=0D +#include // Reference to header file in opensbi=0D +#include // Reference to header file in opensbi=0D +=0D +//=0D +// Indicates the boot hart (PcdBootHartId) OpenSBI initialization is done.= =0D +//=0D +atomic_t BootHartDone =3D ATOMIC_INITIALIZER(0);=0D +atomic_t NonBootHartMessageLock =3D ATOMIC_INITIALIZER(0);=0D +=0D +typedef struct sbi_scratch *(*hartid2scratch)(ulong hartid, ulong hartinde= x);=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 +/**=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 + 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, "%a: FV at %p does not have FV header signature\n= ", __FUNCTION__, Fv));=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 +=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 *(UINT32*) File->Size & 0xffffff;=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 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, "%a: Unable to find PEI Core image\n", __FUNCTI= ON__));=0D + return Status;=0D + }=0D + }=0D + DEBUG ((DEBUG_INFO, "%a: PeiCoreImageBase found\n", __FUNCTION__));=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 + *PeiCoreImageBase =3D 0;=0D +=0D + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));=0D + FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);=0D +}=0D +=0D +/*=0D + Find and return Pei Core entry point.=0D +=0D + It also find SEC and PEI Core file debug inforamtion. 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 PeiCoreImageBase;=0D +=0D + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));=0D +=0D + FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);=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 + DEBUG ((DEBUG_INFO, "%a: PeCoffLoaderGetEntryPoint success: %x\n", __FUN= CTION__, *PeiCoreEntryPoint));=0D +=0D + return;=0D +}=0D +/*=0D + Print out the content of firmware context.=0D +=0D +**/=0D +VOID=0D +DebutPrintFirmwareContext (=0D + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext=0D + )=0D +{=0D + DEBUG ((DEBUG_INFO, "%a: OpenSBI Firmware Context at 0x%x\n", __FUNCTION= __, FirmwareContext));=0D + DEBUG ((DEBUG_INFO, "%a: PEI Service at 0x%x\n\n", __FUNCTI= ON__, FirmwareContext->PeiServiceTable));=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_OPENSBI_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 + SbiGetFirmwareContext (&FirmwareContext);=0D + FirmwareContext =3D (VOID *)FirmwareContext + (unsigned long)((UINTN)New= Stack - (UINTN)OldStack);=0D + SbiSetFirmwareContext (FirmwareContext);=0D +=0D + //=0D + // Relocate PEI Service **=0D + //=0D + FirmwareContext->PeiServiceTable +=3D (unsigned long)((UINTN)NewStack - = (UINTN)OldStack);=0D + DEBUG ((DEBUG_INFO, "%a: OpenSBI Firmware Context is relocated to 0x%x\n= ", __FUNCTION__, FirmwareContext));=0D + DebutPrintFirmwareContext ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)Firmwar= eContext);=0D +=0D + register uintptr_t a0 asm ("a0") =3D (uintptr_t)((UINTN)NewStack - (UINT= N)OldStack);=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 +=0D +/** Handles SBI calls of EDK2's SBI FW extension=0D +=0D + @param[in] ExtId The extension ID of the FW extension.=0D + @param[in] FuncId The called function ID.=0D + @param[in] Args The args to the function.=0D + @param[out] OutVal The value the function returns to the caller.=0D + @param[out] OutTrap Trap info for trapping further, see OpenSBI cod= e.=0D + Is ignored if return value is not SBI_ETRAP.=0D +=0D + @retval 0 If the handler succeeds.=0D + @retval SBI_ENOTSUPP If there's no function with the given ID.=0D + @retval SBI_ETRAP If the called SBI functions wants to trap furth= er.=0D +**/=0D +STATIC int SbiEcallFirmwareHandler (=0D + IN unsigned long ExtId,=0D + IN unsigned long FuncId,=0D + IN unsigned long *Args,=0D + OUT unsigned long *OutVal,=0D + OUT struct sbi_trap_info *OutTrap=0D + )=0D +{=0D + int Ret =3D 0;=0D +=0D + switch (FuncId) {=0D + case SBI_EXT_FW_MSCRATCH_FUNC:=0D + *OutVal =3D (unsigned long) sbi_scratch_thishart_ptr();=0D + break;=0D + case SBI_EXT_FW_MSCRATCH_HARTID_FUNC:=0D + *OutVal =3D (unsigned long) sbi_hartid_to_scratch (Args[0]);=0D + break;=0D + default:=0D + Ret =3D SBI_ENOTSUPP;=0D + };=0D +=0D + return Ret;=0D +}=0D +=0D +struct sbi_ecall_extension FirmwareEcall =3D {=0D + .extid_start =3D SBI_EDK2_FW_EXT,=0D + .extid_end =3D SBI_EDK2_FW_EXT,=0D + .handle =3D SbiEcallFirmwareHandler,=0D +};=0D +=0D +/** Register EDK2's SBI extension with OpenSBI=0D +=0D + This function returns EFI_STATUS, even though it only ever returns=0D + EFI_SUCCESS. On error it ASSERTs. Looking at OpenSBI code it appears tha= t=0D + registering an extension can only fail if the extension ID is invalid or= was=0D + already registered. Failure is therefore an error of the programmer.=0D +=0D + @retval EFI_SUCCESS If the extension was successfully registered.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +RegisterFirmwareSbiExtension (=0D + VOID=0D + )=0D +{=0D + UINTN Ret;=0D + Ret =3D sbi_ecall_register_extension(&FirmwareEcall);=0D + if (Ret) {=0D + //=0D + // Only fails if the extension ID is invalid or already is registered.= =0D + //=0D + DEBUG ((DEBUG_ERROR, "Failed to register SBI Firmware Extension for ED= K2\n"));=0D + ASSERT(FALSE);=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +/** Transion from SEC phase to PEI phase.=0D +=0D + This function transits to S-mode PEI phase from M-mode SEC phase.=0D +=0D + @param[in] BootHartId Hardware thread ID of boot hart.=0D + @param[in] FuncArg1 Arg1 delivered from previous phase.=0D +=0D +**/=0D +VOID EFIAPI PeiCore (=0D + IN UINTN BootHartId,=0D + IN UINTN FuncArg1=0D + )=0D +{=0D + EFI_SEC_PEI_HAND_OFF SecCoreData;=0D + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;=0D + EFI_FIRMWARE_VOLUME_HEADER *BootFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)Fix= edPcdGet32(PcdRiscVPeiFvBase);=0D + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT FirmwareContext;=0D + struct sbi_scratch *ScratchSpace;=0D + struct sbi_platform *ThisSbiPlatform;=0D + UINT32 HartId;=0D +=0D + FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);=0D +=0D + SecCoreData.DataSize =3D sizeof(EFI_SEC_PEI_HAND_OFF);=0D + SecCoreData.BootFirmwareVolumeBase =3D BootFv;=0D + SecCoreData.BootFirmwareVolumeSize =3D (UINTN) BootFv->FvLength;=0D + SecCoreData.TemporaryRamBase =3D (VOID*)(UINT64) FixedPcdGet32(Pcd= TemporaryRamBase);=0D + SecCoreData.TemporaryRamSize =3D (UINTN) FixedPcdGet32(PcdTempora= ryRamSize);=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 + //=0D + // Print out scratch address of each hart=0D + //=0D + DEBUG ((DEBUG_INFO, "%a: OpenSBI scratch address for each hart:\n", __FU= NCTION__));=0D + for (HartId =3D 0; HartId < SBI_HARTMASK_MAX_BITS; HartId ++) {=0D + SbiGetMscratchHartid (HartId, &ScratchSpace);=0D + if(ScratchSpace !=3D NULL) {=0D + DEBUG((DEBUG_INFO, " Hart %d: 0x%x\n", HartId, ScratchSpace= ));=0D + }=0D + }=0D +=0D + //=0D + // Set up OpepSBI firmware context pointer on boot hart OpenSbi scratch.= =0D + // Firmware context residents in stack and will be switched to memory wh= en=0D + // temporary RAM migration.=0D + //=0D + SbiGetMscratchHartid (BootHartId, &ScratchSpace);=0D + ZeroMem ((VOID *)&FirmwareContext, sizeof (EFI_RISCV_OPENSBI_FIRMWARE_CO= NTEXT));=0D + ThisSbiPlatform =3D (struct sbi_platform *)sbi_platform_ptr(ScratchSpace= );=0D + if (ThisSbiPlatform->opensbi_version > OPENSBI_VERSION) {=0D + DEBUG ((DEBUG_ERROR, "%a: OpenSBI platform table version 0x%x is new= er than OpenSBI version 0x%x.\n"=0D + "There maybe be some backward compatable issues= .\n",=0D + __FUNCTION__,=0D + ThisSbiPlatform->opensbi_version,=0D + OPENSBI_VERSION=0D + ));=0D + ASSERT(FALSE);=0D + }=0D + DEBUG ((DEBUG_INFO, "%a: OpenSBI platform table at address: 0x%x\nFirmwa= re Context is located at 0x%x\n",=0D + __FUNCTION__,=0D + ThisSbiPlatform,=0D + &FirmwareContext=0D + ));=0D + ThisSbiPlatform->firmware_context =3D (unsigned long)&FirmwareContext;=0D + //=0D + // Set firmware context Hart-specific pointer=0D + //=0D + for (HartId =3D 0; HartId < SBI_HARTMASK_MAX_BITS; HartId ++) {=0D + SbiGetMscratchHartid (HartId, &ScratchSpace);=0D + if (ScratchSpace !=3D NULL) {=0D + FirmwareContext.HartSpecific[HartId] =3D=0D + (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)ScratchSpace= - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);=0D + DEBUG ((DEBUG_INFO, "%a: OpenSBI Hart %d Firmware Context Hart-spe= cific at address: 0x%x\n",=0D + __FUNCTION__,=0D + HartId,=0D + FirmwareContext.HartSpecific [HartId]=0D + ));=0D + }=0D + }=0D + //=0D + // Set supervisor translation mode to Bare mode=0D + //=0D + DEBUG ((DEBUG_INFO, "%a: Set Supervisor address mode to Bare-mode.\n", _= _FUNCTION__));=0D + RiscVSetSupervisorAddressTranslationRegister ((UINT64)RISCV_SATP_MODE_OF= F << RISCV_SATP_MODE_BIT_POSITION);=0D +=0D + //=0D + // Transfer the control to the PEI core=0D + //=0D + (*PeiCoreEntryPoint) (&SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateD= ispatchTable);=0D +}=0D +=0D +/**=0D + Register firmware SBI extension and launch PeiCore to the mode specified= in=0D + PcdPeiCorePrivilegeMode;=0D +=0D + To register the SBI extension we stay in M-Mode and then transition here= ,=0D + rather than before in sbi_init.=0D +=0D + @param[in] ThisHartId Hardware thread ID.=0D + @param[in] FuncArg1 Arg1 delivered from previous phase.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +LaunchPeiCore (=0D + IN UINTN ThisHartId,=0D + IN UINTN FuncArg1=0D + )=0D +{=0D + UINT32 PeiCoreMode;=0D +=0D + DEBUG ((DEBUG_INFO, "%a: Set boot hart done.\n", __FUNCTION__));=0D + atomic_write (&BootHartDone, (UINT64)TRUE);=0D + RegisterFirmwareSbiExtension ();=0D +=0D + PeiCoreMode =3D FixedPcdGet32 (PcdPeiCorePrivilegeMode);=0D + if (PeiCoreMode =3D=3D PRV_S) {=0D + DEBUG ((DEBUG_INFO, "%a: Switch to S-Mode for PeiCore.\n", __FUNCTION_= _));=0D + sbi_hart_switch_mode (ThisHartId, FuncArg1, (UINTN)PeiCore, PRV_S, FAL= SE);=0D + } else if (PeiCoreMode =3D=3D PRV_M) {=0D + DEBUG ((DEBUG_INFO, "%a: Switch to M-Mode for PeiCore.\n", __FUNCTION_= _));=0D + PeiCore (ThisHartId, FuncArg1);=0D + } else {=0D + DEBUG ((DEBUG_INFO, "%a: The privilege mode specified in PcdPeiCorePri= vilegeMode is not supported.\n", __FUNCTION__));=0D + while (TRUE);=0D + }=0D +}=0D +=0D +/**=0D + Interface to invoke internal mode switch function.=0D +=0D + To register the SBI extension we stay in M-Mode and then transition here= ,=0D + rather than before in sbi_init.=0D +=0D + @param[in] FuncArg0 Arg0 to pass to next phase entry point addres= s.=0D + @param[in] FuncArg1 Arg1 to pass to next phase entry point addres= s.=0D + @param[in] NextAddr Entry point of next phase.=0D + @param[in] NextMode Privilege mode of next phase.=0D + @param[in] NextVirt Next phase is in virtualiztion.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +RiscVOpenSbiHartSwitchMode (=0D + IN UINTN FuncArg0,=0D + IN UINTN FuncArg1,=0D + IN UINTN NextAddr,=0D + IN UINTN NextMode,=0D + IN BOOLEAN NextVirt=0D + )=0D +{=0D + sbi_hart_switch_mode(FuncArg0, FuncArg1, NextAddr, NextMode, NextVirt);= =0D +}=0D +=0D +/**=0D + This function initilizes hart specific information and SBI.=0D + For the boot hart, it boots system through PEI core and initial SBI in t= he DXE IPL.=0D + For others, it goes to initial SBI and halt.=0D +=0D + the lay out of memory region for each hart is as below delineates,=0D +=0D + _ = ____=0D + |----Scratch ends | = |=0D + | | sizeof (sbi_scratch) = |=0D + | _| = |=0D + |----Scratch buffer starts <----- *Scratch = |=0D + |----Firmware Context Hart-specific ends _ = |=0D + | | = |=0D + | | FIRMWARE_CONTEXT_HART_SP= ECIFIC_SIZE |=0D + | | = | PcdOpenSbiStackSize=0D + | _| = |=0D + |----Firmware Context Hart-specific starts <----- **HartFirmwareContex= t |=0D + |----Hart stack top _ = |=0D + | | = |=0D + | | = |=0D + | | Stack = |=0D + | | = |=0D + | _| = ____|=0D + |----Hart stack bottom=0D +=0D + @param[in] HartId Hardware thread ID.=0D + @param[in] Scratch Pointer to sbi_scratch structure.=0D +=0D +**/=0D +VOID EFIAPI SecCoreStartUpWithStack(=0D + IN UINTN HartId,=0D + IN struct sbi_scratch *Scratch=0D + )=0D +{=0D + UINT64 BootHartDoneSbiInit;=0D + UINT64 NonBootHartMessageLockValue;=0D + EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartFirmwareContext;=0D +=0D + //=0D + // Setup EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC for each hart.=0D + //=0D + HartFirmwareContext =3D (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UI= NT8 *)Scratch - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);=0D + HartFirmwareContext->IsaExtensionSupported =3D RiscVReadMachineIsa ();=0D + HartFirmwareContext->MachineVendorId.Value64_L =3D RiscVReadMachineVendo= rId ();=0D + HartFirmwareContext->MachineVendorId.Value64_H =3D 0;=0D + HartFirmwareContext->MachineArchId.Value64_L =3D RiscVReadMachineArchite= ctureId ();=0D + HartFirmwareContext->MachineArchId.Value64_H =3D 0;=0D + HartFirmwareContext->MachineImplId.Value64_L =3D RiscVReadMachineImpleme= ntId ();=0D + HartFirmwareContext->MachineImplId.Value64_H =3D 0;=0D + HartFirmwareContext->HartSwitchMode =3D RiscVOpenSbiHartSwitchMode;=0D +=0D + if (HartId =3D=3D FixedPcdGet32(PcdBootHartId)) {=0D + Scratch->next_addr =3D (UINTN)LaunchPeiCore;=0D + Scratch->next_mode =3D PRV_M;=0D + DEBUG ((DEBUG_INFO, "%a: Initializing OpenSBI library for booting hart= %d\n", __FUNCTION__, HartId));=0D + sbi_init(Scratch);=0D + }=0D +=0D + //=0D + // Initialize the non boot harts=0D + //=0D + do {=0D + BootHartDoneSbiInit =3D atomic_read (&BootHartDone);=0D + //=0D + // Below leave some memory cycles to boot hart=0D + // for updating BootHartDone.=0D + //=0D + CpuPause ();=0D + CpuPause ();=0D + CpuPause ();=0D + } while (BootHartDoneSbiInit !=3D (UINT64)TRUE);=0D +=0D + NonBootHartMessageLockValue =3D atomic_xchg(&NonBootHartMessageLock, TRU= E);=0D + while (NonBootHartMessageLockValue =3D=3D TRUE) {=0D + CpuPause ();=0D + CpuPause ();=0D + CpuPause ();=0D + NonBootHartMessageLockValue =3D atomic_xchg(&NonBootHartMessageLock, T= RUE);=0D + };=0D + DEBUG((DEBUG_INFO, "%a: Non boot hart %d initialization.\n", __FUNCTION_= _, HartId));=0D + NonBootHartMessageLockValue =3D atomic_xchg(&NonBootHartMessageLock, FAL= SE);=0D + //=0D + // Non boot hart wiil be halted waiting for SBI_HART_STARTING.=0D + // Use HSM ecall to start non boot hart (SBI_EXT_HSM_HART_START) later o= n,=0D + //=0D + sbi_init(Scratch);=0D +}=0D +=0D diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S b= /Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S new file mode 100644 index 0000000000..6b2cdb6c17 --- /dev/null +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S @@ -0,0 +1,532 @@ +/*=0D + * Copyright (c) 2020 , Hewlett Packard Enterprise Development LP. All rig= hts reserved.=0D + *=0D + * SPDX-License-Identifier: BSD-2-Clause=0D + *=0D + * Copyright (c) 2019 Western Digital Corporation or its affiliates.=0D + *=0D + */=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#include =0D +=0D +.text=0D +.align 3=0D +=0D +ASM_FUNC (_ModuleEntryPoint)=0D + /*=0D + * Jump to warm-boot if this is not the selected core booting,=0D + */=0D + csrr a6, CSR_MHARTID=0D + li a5, FixedPcdGet32 (PcdBootHartId)=0D + bne a6, a5, _wait_for_boot_hart=0D +=0D + li ra, 0=0D + call _reset_regs=0D +=0D + /* Preload HART details=0D + * s7 -> HART Count=0D + * s8 -> HART Stack Size=0D + */=0D + li s7, FixedPcdGet32 (PcdHartCount)=0D + li s8, FixedPcdGet32 (PcdOpenSbiStackSize)=0D +=0D + /*=0D + * Setup scratch space for all the HARTs=0D + *=0D + * Scratch buffer is on the top of stack buffer=0D + * of each hart.=0D + *=0D + * tp : Base address of scratch buffer.=0D + * s7 : HART Count=0D + * s8 : HART Stack Size=0D + */=0D + li tp, FixedPcdGet32 (PcdScratchRamBase)=0D + mul a5, s7, s8=0D + add tp, tp, a5=0D +=0D + /* Keep a copy of tp */=0D + add t3, tp, zero=0D + /* Counter */=0D + li t2, 1=0D + /* hartid 0 is mandated by ISA */=0D + li t1, 0=0D +_scratch_init:=0D + add tp, t3, zero=0D + mul a5, s8, t1=0D + sub tp, tp, a5=0D + li a5, SBI_SCRATCH_SIZE=0D + sub tp, tp, a5=0D +=0D + /* Initialize scratch space */=0D +=0D + /* Firmware range and size */=0D + li a4, FixedPcdGet32 (PcdFwStartAddress)=0D + li a5, FixedPcdGet32 (PcdFwEndAddress)=0D + sub a5, a5, a4=0D + sd a4, SBI_SCRATCH_FW_START_OFFSET(tp)=0D + sd a5, SBI_SCRATCH_FW_SIZE_OFFSET(tp)=0D +=0D + /*=0D + * Note: fw_next_arg1() uses a0, a1, and ra=0D + */=0D + call fw_next_arg1=0D + sd a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp) /* Save agr1 in scratch buffe= r*/=0D + /*=0D + Note: fw_next_addr()uses a0, a1, and ra=0D + */=0D + call fw_next_addr=0D + sd a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp) /* Save next address in scrat= ch buffer*/=0D + li a4, PRV_S=0D + sd a4, SBI_SCRATCH_NEXT_MODE_OFFSET(tp) /* Save next mode in scratch = buffer*/=0D + la a4, _start_warm=0D + sd a4, SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp) /* Save warm boot address= in scratch buffer*/=0D + la a4, platform=0D + sd a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp) /* Save platfrom table in= scratch buffer*/=0D + la a4, _hartid_to_scratch=0D + sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp) /* Save _hartid_to_sc= ratch function in scratch buffer*/=0D + sd zero, SBI_SCRATCH_TMP0_OFFSET(tp)=0D +=0D +#ifdef FW_OPTIONS=0D + li a4, FW_OPTIONS=0D + sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp)=0D +#else=0D + sd zero, SBI_SCRATCH_OPTIONS_OFFSET(tp)=0D +#endif=0D + add t1, t1, t2=0D + /* Loop to next hart */=0D + blt t1, s7, _scratch_init=0D +=0D + /* Fill-out temporary memory with 55aa*/=0D + li a4, FixedPcdGet32 (PcdTemporaryRamBase)=0D + li a5, FixedPcdGet32 (PcdTemporaryRamSize)=0D + add a5, a4, a5=0D +1:=0D + li a3, 0x5AA55AA55AA55AA5=0D + sd a3, (a4)=0D + add a4, a4, __SIZEOF_POINTER__=0D + blt a4, a5, 1b=0D +=0D + /* Update boot hart flag */=0D + la a4, _boot_hart_done=0D + li a5, 1=0D + sd a5, (a4)=0D +=0D + /* Wait for boot hart */=0D +_wait_for_boot_hart:=0D + la a4, _boot_hart_done=0D + ld a5, (a4)=0D +=0D + /* Reduce the bus traffic so that boot hart may proceed faster */=0D + nop=0D + nop=0D + nop=0D + beqz a5, _wait_for_boot_hart=0D +=0D +_start_warm:=0D + li ra, 0=0D + call _reset_regs=0D +=0D + /* Disable and clear all interrupts */=0D + csrw CSR_MIE, zero=0D + csrw CSR_MIP, zero=0D +=0D + li s7, FixedPcdGet32 (PcdBootableHartNumber)=0D + li s8, FixedPcdGet32 (PcdOpenSbiStackSize)=0D + la a4, platform=0D +=0D + /* s9 is hart_index2id array */=0D + REG_L s9, SBI_PLATFORM_HART_INDEX2ID_OFFSET(a4)=0D +=0D + /* s6 is this hart ID */=0D + csrr s6, CSR_MHARTID=0D +=0D + /*=0D + * Convert hart ID to scratch buffer=0D + * Because the hert ID maybe not in sequentially=0D + */=0D + beqz s9, 3f=0D + li a4, 0=0D +1:=0D +#if __riscv_xlen =3D=3D 64=0D + lwu a5, (s9)=0D +#else=0D + lw a5, (s9)=0D +#endif=0D + /* Branch if hart ID is matched */=0D + beq a5, s6, 2f=0D + add s9, s9, 4=0D + add a4, a4, 1=0D + /* Loop to next index */=0D + blt a4, s7, 1b=0D + li a4, -1=0D +2:=0D + add s6, a4, zero=0D +3:=0D + /* Jump to UninitializedHartWait for the non-bootable harts.=0D + Be aware that the stack and scratch is not set=0D + at this moment for this hart even the resource=0D + is preserved eariler for it.=0D + */=0D + bltu s6, s7, 4f=0D + csrr a0, CSR_MHARTID=0D + j _uninitialized_hart_wait=0D +4:=0D + li s7, FixedPcdGet32 (PcdHartCount)=0D + /* Find the scratch space for this hart=0D + *=0D + * Scratch buffer is on the top of stack buffer=0D + * reserved for opensbi.=0D + *=0D + * tp: The base address of scratch buffer=0D + * s6: Index to scratch buffer fot this hart=0D + * s7: Total hart number=0D + * s8: Stack size for opebsbi.=0D + */=0D + li tp, FixedPcdGet32 (PcdScratchRamBase)=0D + mul a5, s7, s8=0D + add tp, tp, a5=0D + mul a5, s8, s6=0D + sub tp, tp, a5=0D + li a5, SBI_SCRATCH_SIZE=0D + sub tp, tp, a5=0D +=0D + /* update the mscratch */=0D + csrw CSR_MSCRATCH, tp=0D +=0D + /*make room for Hart specific Firmware Context*/=0D + li a5, FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE=0D + sub tp, tp, a5=0D +=0D + /* Setup stack */=0D + add sp, tp, zero=0D +=0D + /* Setup stack for the Hart executing EFI to top of temporary ram*/=0D + csrr a6, CSR_MHARTID=0D + li a5, FixedPcdGet32 (PcdBootHartId)=0D + bne a6, a5, 1f=0D +=0D + li a4, FixedPcdGet32(PcdTemporaryRamBase)=0D + li a5, FixedPcdGet32(PcdTemporaryRamSize)=0D + add sp, a4, a5=0D +1:=0D +=0D + /* Setup trap handler */=0D + la a4, _trap_handler=0D + csrw CSR_MTVEC, a4=0D +=0D + /* Make sure that mtvec is updated */=0D + 1:=0D + csrr a5, CSR_MTVEC=0D + bne a4, a5, 1b=0D +=0D + /* Call library constructors before jup to SEC core */=0D + call ProcessLibraryConstructorList=0D +=0D + /* Jump to SEC Core C=0D + * a0: HART ID=0D + * a1: Scratch pointer=0D + */=0D + csrr a0, CSR_MHARTID=0D + csrr a1, CSR_MSCRATCH=0D + call SecCoreStartUpWithStack=0D +=0D + /* We do not expect to reach here hence just hang */=0D + j _start_hang=0D +=0D + .align 3=0D + .section .data, "aw"=0D +_boot_hart_done:=0D + RISCV_PTR 0=0D +=0D + .align 3=0D + .section .entry, "ax", %progbits=0D + .globl _hartid_to_scratch=0D +=0D + /*=0D + * a0 -> HART id (Obsoleted, keep this for the backward compatible)=0D + * a1 -> HART index (0-based) of this hart id=0D + */=0D +_hartid_to_scratch:=0D + add sp, sp, -(3 * __SIZEOF_POINTER__)=0D + sd s0, (sp)=0D + sd s1, (__SIZEOF_POINTER__)(sp)=0D + sd s2, (__SIZEOF_POINTER__ * 2)(sp)=0D +=0D + /*=0D + * s0 -> HART Stack Size=0D + * s1 -> HART Stack End=0D + * s2 -> Temporary=0D + */=0D + la s2, platform=0D +#if __riscv_xlen =3D=3D 64=0D + lwu s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)=0D +#else=0D + lw s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)=0D +#endif=0D + li s2, FixedPcdGet32 (PcdHartCount)=0D +=0D + mul s2, s2, s0=0D + li s1, FixedPcdGet32 (PcdScratchRamBase)=0D + add s1, s1, s2=0D + mul s2, s0, a1=0D + sub s1, s1, s2=0D + li s2, SBI_SCRATCH_SIZE=0D + sub a0, s1, s2=0D + ld s0, (sp)=0D + ld s1, (__SIZEOF_POINTER__)(sp)=0D + ld s2, (__SIZEOF_POINTER__ * 2)(sp)=0D + add sp, sp, (3 * __SIZEOF_POINTER__)=0D + ret=0D +=0D + .align 3=0D + .section .entry, "ax", %progbits=0D + .globl _start_hang=0D +_start_hang:=0D + wfi=0D + j _start_hang=0D +=0D + /*=0D + * Uninitialized hart comes here and wait=0D + * for the further process.=0D + * a0: hart ID.=0D + */=0D +_uninitialized_hart_wait:=0D + wfi=0D + j _uninitialized_hart_wait=0D +=0D + .align 3=0D + .section .entry, "ax", %progbits=0D + .align 3=0D + .globl _trap_handler=0D +_trap_handler:=0D +=0D + /* Swap TP and MSCRATCH */=0D + csrrw tp, CSR_MSCRATCH, tp=0D +=0D + /* Save T0 in scratch space */=0D + REG_S t0, SBI_SCRATCH_TMP0_OFFSET(tp)=0D +=0D + /* Check which mode we came from */=0D + csrr t0, CSR_MSTATUS=0D + srl t0, t0, MSTATUS_MPP_SHIFT=0D + and t0, t0, PRV_M=0D + xori t0, t0, PRV_M=0D + beq t0, zero, _trap_handler_m_mode=0D +=0D + /* We came from S-mode or U-mode */=0D +_trap_handler_s_mode:=0D + /* Set T0 to original SP */=0D + add t0, sp, zero=0D +=0D + /* Setup exception stack */=0D + add sp, tp, -(SBI_TRAP_REGS_SIZE)=0D +=0D + /* Jump to code common for all modes */=0D + j _trap_handler_all_mode=0D +=0D + /* We came from M-mode */=0D +_trap_handler_m_mode:=0D + /* Set T0 to original SP */=0D + add t0, sp, zero=0D +=0D + /* Re-use current SP as exception stack */=0D + add sp, sp, -(SBI_TRAP_REGS_SIZE)=0D +=0D +_trap_handler_all_mode:=0D + /* Save original SP (from T0) on stack */=0D + REG_S t0, SBI_TRAP_REGS_OFFSET(sp)(sp)=0D +=0D + /* Restore T0 from scratch space */=0D + REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp)=0D +=0D + /* Save T0 on stack */=0D + REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp)=0D +=0D + /* Swap TP and MSCRATCH */=0D + csrrw tp, CSR_MSCRATCH, tp=0D +=0D + /* Save MEPC and MSTATUS CSRs */=0D + csrr t0, CSR_MEPC=0D + REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)=0D + csrr t0, CSR_MSTATUS=0D + REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)=0D + REG_S zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)=0D +#if __riscv_xlen =3D=3D 32=0D + csrr t0, CSR_MISA=0D + srli t0, t0, ('H' - 'A')=0D + andi t0, t0, 0x1=0D + beq t0, zero, _skip_mstatush_save=0D + csrr t0, CSR_MSTATUSH=0D + REG_S t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)=0D +_skip_mstatush_save:=0D +#endif=0D +=0D + /* Save all general registers except SP and T0 */=0D + REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp)=0D + REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp)=0D + REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp)=0D + REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp)=0D + REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp)=0D + REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp)=0D + REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp)=0D + REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp)=0D + REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp)=0D + REG_S a1, SBI_TRAP_REGS_OFFSET(a1)(sp)=0D + REG_S a2, SBI_TRAP_REGS_OFFSET(a2)(sp)=0D + REG_S a3, SBI_TRAP_REGS_OFFSET(a3)(sp)=0D + REG_S a4, SBI_TRAP_REGS_OFFSET(a4)(sp)=0D + REG_S a5, SBI_TRAP_REGS_OFFSET(a5)(sp)=0D + REG_S a6, SBI_TRAP_REGS_OFFSET(a6)(sp)=0D + REG_S a7, SBI_TRAP_REGS_OFFSET(a7)(sp)=0D + REG_S s2, SBI_TRAP_REGS_OFFSET(s2)(sp)=0D + REG_S s3, SBI_TRAP_REGS_OFFSET(s3)(sp)=0D + REG_S s4, SBI_TRAP_REGS_OFFSET(s4)(sp)=0D + REG_S s5, SBI_TRAP_REGS_OFFSET(s5)(sp)=0D + REG_S s6, SBI_TRAP_REGS_OFFSET(s6)(sp)=0D + REG_S s7, SBI_TRAP_REGS_OFFSET(s7)(sp)=0D + REG_S s8, SBI_TRAP_REGS_OFFSET(s8)(sp)=0D + REG_S s9, SBI_TRAP_REGS_OFFSET(s9)(sp)=0D + REG_S s10, SBI_TRAP_REGS_OFFSET(s10)(sp)=0D + REG_S s11, SBI_TRAP_REGS_OFFSET(s11)(sp)=0D + REG_S t3, SBI_TRAP_REGS_OFFSET(t3)(sp)=0D + REG_S t4, SBI_TRAP_REGS_OFFSET(t4)(sp)=0D + REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp)=0D + REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp)=0D +=0D + /* Call C routine */=0D + add a0, sp, zero=0D + call sbi_trap_handler=0D +=0D + /* Restore all general registers except SP and T0 */=0D + REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp)=0D + REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(sp)=0D + REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(sp)=0D + REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(sp)=0D + REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(sp)=0D + REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(sp)=0D + REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(sp)=0D + REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(sp)=0D + REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(sp)=0D + REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(sp)=0D + REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(sp)=0D + REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(sp)=0D + REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(sp)=0D + REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(sp)=0D + REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(sp)=0D + REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(sp)=0D + REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(sp)=0D + REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(sp)=0D + REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(sp)=0D + REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(sp)=0D + REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(sp)=0D + REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(sp)=0D + REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(sp)=0D + REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(sp)=0D + REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(sp)=0D + REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(sp)=0D + REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(sp)=0D + REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp)=0D + REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp)=0D +=0D + /* Restore MEPC and MSTATUS CSRs */=0D + REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)=0D + csrw CSR_MEPC, t0=0D + REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)=0D + csrw CSR_MSTATUS, t0=0D +#if __riscv_xlen =3D=3D 32=0D + csrr t0, CSR_MISA=0D + srli t0, t0, ('H' - 'A')=0D + andi t0, t0, 0x1=0D + beq t0, zero, _skip_mstatush_restore=0D + REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)=0D + csrw CSR_MSTATUSH, t0=0D +_skip_mstatush_restore:=0D +#endif=0D +=0D + /* Restore T0 */=0D + REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp)=0D +=0D + /* Restore SP */=0D + REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(sp)=0D +=0D + mret=0D +=0D + .align 3=0D + .section .entry, "ax", %progbits=0D + .globl _reset_regs=0D +_reset_regs:=0D +=0D + /* flush the instruction cache */=0D + fence.i=0D +=0D + /* Reset all registers except ra, a0,a1 */=0D + li sp, 0=0D + li gp, 0=0D + li tp, 0=0D + li t0, 0=0D + li t1, 0=0D + li t2, 0=0D + li s0, 0=0D + li s1, 0=0D + li a2, 0=0D + li a3, 0=0D + li a4, 0=0D + li a5, 0=0D + li a6, 0=0D + li a7, 0=0D + li s2, 0=0D + li s3, 0=0D + li s4, 0=0D + li s5, 0=0D + li s6, 0=0D + li s7, 0=0D + li s8, 0=0D + li s9, 0=0D + li s10, 0=0D + li s11, 0=0D + li t3, 0=0D + li t4, 0=0D + li t5, 0=0D + li t6, 0=0D + csrw CSR_MSCRATCH, 0=0D + ret=0D +=0D + .align 3=0D + .section .entry, "ax", %progbits=0D + .global fw_prev_arg1=0D +fw_prev_arg1:=0D +=0D + /* We return previous arg1 in 'a0' */=0D + add a0, zero, zero=0D + ret=0D +=0D + .align 3=0D + .section .entry, "ax", %progbits=0D + .global fw_next_arg1=0D +fw_next_arg1:=0D + /* We return next arg1 in 'a0' */=0D + li a0, FixedPcdGet32(PcdRiscVPeiFvBase)=0D + ret=0D +=0D + .align 3=0D + .section .entry, "ax", %progbits=0D + .global fw_next_addr=0D +fw_next_addr:=0D + /* We return next address in 'a0' */=0D + la a0, _jump_addr=0D + ld a0, (a0)=0D + ret=0D +=0D + .align 3=0D + .section .entry, "ax", %progbits=0D +_jump_addr:=0D +RISCV_PTR SecCoreStartUpWithStack=0D --=20 2.31.1