123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- /** @file
- Entry point to the Standalone MM Foundation when initialized during the SEC
- phase on ARM platforms
- Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <PiMm.h>
- #include <Library/Arm/StandaloneMmCoreEntryPoint.h>
- #include <PiPei.h>
- #include <Guid/MmramMemoryReserve.h>
- #include <Guid/MpInformation.h>
- #include <Library/ArmMmuLib.h>
- #include <Library/ArmSvcLib.h>
- #include <Library/DebugLib.h>
- #include <Library/HobLib.h>
- #include <Library/BaseLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/SerialPortLib.h>
- #include <Library/PcdLib.h>
- #include <IndustryStandard/ArmStdSmc.h>
- #include <IndustryStandard/ArmMmSvc.h>
- #include <IndustryStandard/ArmFfaSvc.h>
- #define SPM_MAJOR_VER_MASK 0xFFFF0000
- #define SPM_MINOR_VER_MASK 0x0000FFFF
- #define SPM_MAJOR_VER_SHIFT 16
- #define FFA_NOT_SUPPORTED -1
- STATIC CONST UINT32 mSpmMajorVer = SPM_MAJOR_VERSION;
- STATIC CONST UINT32 mSpmMinorVer = SPM_MINOR_VERSION;
- STATIC CONST UINT32 mSpmMajorVerFfa = SPM_MAJOR_VERSION_FFA;
- STATIC CONST UINT32 mSpmMinorVerFfa = SPM_MINOR_VERSION_FFA;
- #define BOOT_PAYLOAD_VERSION 1
- PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint = NULL;
- /**
- Retrieve a pointer to and print the boot information passed by privileged
- secure firmware.
- @param [in] SharedBufAddress The pointer memory shared with privileged
- firmware.
- **/
- EFI_SECURE_PARTITION_BOOT_INFO *
- GetAndPrintBootinformation (
- IN VOID *SharedBufAddress
- )
- {
- EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;
- EFI_SECURE_PARTITION_CPU_INFO *PayloadCpuInfo;
- UINTN Index;
- PayloadBootInfo = (EFI_SECURE_PARTITION_BOOT_INFO *) SharedBufAddress;
- if (PayloadBootInfo == NULL) {
- DEBUG ((DEBUG_ERROR, "PayloadBootInfo NULL\n"));
- return NULL;
- }
- if (PayloadBootInfo->Header.Version != BOOT_PAYLOAD_VERSION) {
- DEBUG ((DEBUG_ERROR, "Boot Information Version Mismatch. Current=0x%x, Expected=0x%x.\n",
- PayloadBootInfo->Header.Version, BOOT_PAYLOAD_VERSION));
- return NULL;
- }
- DEBUG ((DEBUG_INFO, "NumSpMemRegions - 0x%x\n", PayloadBootInfo->NumSpMemRegions));
- DEBUG ((DEBUG_INFO, "SpMemBase - 0x%lx\n", PayloadBootInfo->SpMemBase));
- DEBUG ((DEBUG_INFO, "SpMemLimit - 0x%lx\n", PayloadBootInfo->SpMemLimit));
- DEBUG ((DEBUG_INFO, "SpImageBase - 0x%lx\n", PayloadBootInfo->SpImageBase));
- DEBUG ((DEBUG_INFO, "SpStackBase - 0x%lx\n", PayloadBootInfo->SpStackBase));
- DEBUG ((DEBUG_INFO, "SpHeapBase - 0x%lx\n", PayloadBootInfo->SpHeapBase));
- DEBUG ((DEBUG_INFO, "SpNsCommBufBase - 0x%lx\n", PayloadBootInfo->SpNsCommBufBase));
- DEBUG ((DEBUG_INFO, "SpSharedBufBase - 0x%lx\n", PayloadBootInfo->SpSharedBufBase));
- DEBUG ((DEBUG_INFO, "SpImageSize - 0x%x\n", PayloadBootInfo->SpImageSize));
- DEBUG ((DEBUG_INFO, "SpPcpuStackSize - 0x%x\n", PayloadBootInfo->SpPcpuStackSize));
- DEBUG ((DEBUG_INFO, "SpHeapSize - 0x%x\n", PayloadBootInfo->SpHeapSize));
- DEBUG ((DEBUG_INFO, "SpNsCommBufSize - 0x%x\n", PayloadBootInfo->SpNsCommBufSize));
- DEBUG ((DEBUG_INFO, "SpPcpuSharedBufSize - 0x%x\n", PayloadBootInfo->SpPcpuSharedBufSize));
- DEBUG ((DEBUG_INFO, "NumCpus - 0x%x\n", PayloadBootInfo->NumCpus));
- DEBUG ((DEBUG_INFO, "CpuInfo - 0x%p\n", PayloadBootInfo->CpuInfo));
- PayloadCpuInfo = (EFI_SECURE_PARTITION_CPU_INFO *) PayloadBootInfo->CpuInfo;
- if (PayloadCpuInfo == NULL) {
- DEBUG ((DEBUG_ERROR, "PayloadCpuInfo NULL\n"));
- return NULL;
- }
- for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {
- DEBUG ((DEBUG_INFO, "Mpidr - 0x%lx\n", PayloadCpuInfo[Index].Mpidr));
- DEBUG ((DEBUG_INFO, "LinearId - 0x%x\n", PayloadCpuInfo[Index].LinearId));
- DEBUG ((DEBUG_INFO, "Flags - 0x%x\n", PayloadCpuInfo[Index].Flags));
- }
- return PayloadBootInfo;
- }
- /**
- A loop to delegated events.
- @param [in] EventCompleteSvcArgs Pointer to the event completion arguments.
- **/
- VOID
- EFIAPI
- DelegatedEventLoop (
- IN ARM_SVC_ARGS *EventCompleteSvcArgs
- )
- {
- BOOLEAN FfaEnabled;
- EFI_STATUS Status;
- UINTN SvcStatus;
- while (TRUE) {
- ArmCallSvc (EventCompleteSvcArgs);
- DEBUG ((DEBUG_INFO, "Received delegated event\n"));
- DEBUG ((DEBUG_INFO, "X0 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg0));
- DEBUG ((DEBUG_INFO, "X1 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg1));
- DEBUG ((DEBUG_INFO, "X2 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg2));
- DEBUG ((DEBUG_INFO, "X3 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg3));
- DEBUG ((DEBUG_INFO, "X4 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg4));
- DEBUG ((DEBUG_INFO, "X5 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg5));
- DEBUG ((DEBUG_INFO, "X6 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg6));
- DEBUG ((DEBUG_INFO, "X7 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg7));
- FfaEnabled = FeaturePcdGet (PcdFfaEnable);
- if (FfaEnabled) {
- Status = CpuDriverEntryPoint (
- EventCompleteSvcArgs->Arg0,
- EventCompleteSvcArgs->Arg6,
- EventCompleteSvcArgs->Arg3
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed delegated event 0x%x, Status 0x%x\n",
- EventCompleteSvcArgs->Arg3, Status));
- }
- } else {
- Status = CpuDriverEntryPoint (
- EventCompleteSvcArgs->Arg0,
- EventCompleteSvcArgs->Arg3,
- EventCompleteSvcArgs->Arg1
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed delegated event 0x%x, Status 0x%x\n",
- EventCompleteSvcArgs->Arg0, Status));
- }
- }
- switch (Status) {
- case EFI_SUCCESS:
- SvcStatus = ARM_SVC_SPM_RET_SUCCESS;
- break;
- case EFI_INVALID_PARAMETER:
- SvcStatus = ARM_SVC_SPM_RET_INVALID_PARAMS;
- break;
- case EFI_ACCESS_DENIED:
- SvcStatus = ARM_SVC_SPM_RET_DENIED;
- break;
- case EFI_OUT_OF_RESOURCES:
- SvcStatus = ARM_SVC_SPM_RET_NO_MEMORY;
- break;
- case EFI_UNSUPPORTED:
- SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;
- break;
- default:
- SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;
- break;
- }
- if (FfaEnabled) {
- EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;
- EventCompleteSvcArgs->Arg1 = 0;
- EventCompleteSvcArgs->Arg2 = 0;
- EventCompleteSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;
- EventCompleteSvcArgs->Arg4 = SvcStatus;
- } else {
- EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;
- EventCompleteSvcArgs->Arg1 = SvcStatus;
- }
- }
- }
- /**
- Query the SPM version, check compatibility and return success if compatible.
- @retval EFI_SUCCESS SPM versions compatible.
- @retval EFI_UNSUPPORTED SPM versions not compatible.
- **/
- STATIC
- EFI_STATUS
- GetSpmVersion (VOID)
- {
- EFI_STATUS Status;
- UINT16 CalleeSpmMajorVer;
- UINT16 CallerSpmMajorVer;
- UINT16 CalleeSpmMinorVer;
- UINT16 CallerSpmMinorVer;
- UINT32 SpmVersion;
- ARM_SVC_ARGS SpmVersionArgs;
- if (FeaturePcdGet (PcdFfaEnable)) {
- SpmVersionArgs.Arg0 = ARM_SVC_ID_FFA_VERSION_AARCH32;
- SpmVersionArgs.Arg1 = mSpmMajorVerFfa << SPM_MAJOR_VER_SHIFT;
- SpmVersionArgs.Arg1 |= mSpmMinorVerFfa;
- CallerSpmMajorVer = mSpmMajorVerFfa;
- CallerSpmMinorVer = mSpmMinorVerFfa;
- } else {
- SpmVersionArgs.Arg0 = ARM_SVC_ID_SPM_VERSION_AARCH32;
- CallerSpmMajorVer = mSpmMajorVer;
- CallerSpmMinorVer = mSpmMinorVer;
- }
- ArmCallSvc (&SpmVersionArgs);
- SpmVersion = SpmVersionArgs.Arg0;
- if (SpmVersion == FFA_NOT_SUPPORTED) {
- return EFI_UNSUPPORTED;
- }
- CalleeSpmMajorVer = ((SpmVersion & SPM_MAJOR_VER_MASK) >> SPM_MAJOR_VER_SHIFT);
- CalleeSpmMinorVer = ((SpmVersion & SPM_MINOR_VER_MASK) >> 0);
- // Different major revision values indicate possibly incompatible functions.
- // For two revisions, A and B, for which the major revision values are
- // identical, if the minor revision value of revision B is greater than
- // the minor revision value of revision A, then every function in
- // revision A must work in a compatible way with revision B.
- // However, it is possible for revision B to have a higher
- // function count than revision A.
- if ((CalleeSpmMajorVer == CallerSpmMajorVer) &&
- (CalleeSpmMinorVer >= CallerSpmMinorVer))
- {
- DEBUG ((DEBUG_INFO, "SPM Version: Major=0x%x, Minor=0x%x\n",
- CalleeSpmMajorVer, CalleeSpmMinorVer));
- Status = EFI_SUCCESS;
- }
- else
- {
- DEBUG ((DEBUG_INFO, "Incompatible SPM Versions.\n Callee Version: Major=0x%x, Minor=0x%x.\n Caller: Major=0x%x, Minor>=0x%x.\n",
- CalleeSpmMajorVer, CalleeSpmMinorVer, CallerSpmMajorVer, CallerSpmMinorVer));
- Status = EFI_UNSUPPORTED;
- }
- return Status;
- }
- /**
- Initialize parameters to be sent via SVC call.
- @param[out] InitMmFoundationSvcArgs Args structure
- @param[out] Ret Return Code
- **/
- STATIC
- VOID
- InitArmSvcArgs (
- OUT ARM_SVC_ARGS *InitMmFoundationSvcArgs,
- OUT INT32 *Ret
- )
- {
- if (FeaturePcdGet (PcdFfaEnable)) {
- InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;
- InitMmFoundationSvcArgs->Arg1 = 0;
- InitMmFoundationSvcArgs->Arg2 = 0;
- InitMmFoundationSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;
- InitMmFoundationSvcArgs->Arg4 = *Ret;
- } else {
- InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;
- InitMmFoundationSvcArgs->Arg1 = *Ret;
- }
- }
- /**
- The entry point of Standalone MM Foundation.
- @param [in] SharedBufAddress Pointer to the Buffer between SPM and SP.
- @param [in] SharedBufSize Size of the shared buffer.
- @param [in] cookie1 Cookie 1
- @param [in] cookie2 Cookie 2
- **/
- VOID
- EFIAPI
- _ModuleEntryPoint (
- IN VOID *SharedBufAddress,
- IN UINT64 SharedBufSize,
- IN UINT64 cookie1,
- IN UINT64 cookie2
- )
- {
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
- EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;
- ARM_SVC_ARGS InitMmFoundationSvcArgs;
- EFI_STATUS Status;
- INT32 Ret;
- UINT32 SectionHeaderOffset;
- UINT16 NumberOfSections;
- VOID *HobStart;
- VOID *TeData;
- UINTN TeDataSize;
- EFI_PHYSICAL_ADDRESS ImageBase;
- // Get Secure Partition Manager Version Information
- Status = GetSpmVersion ();
- if (EFI_ERROR (Status)) {
- goto finish;
- }
- PayloadBootInfo = GetAndPrintBootinformation (SharedBufAddress);
- if (PayloadBootInfo == NULL) {
- Status = EFI_UNSUPPORTED;
- goto finish;
- }
- // Locate PE/COFF File information for the Standalone MM core module
- Status = LocateStandaloneMmCorePeCoffData (
- (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PayloadBootInfo->SpImageBase,
- &TeData,
- &TeDataSize
- );
- if (EFI_ERROR (Status)) {
- goto finish;
- }
- // Obtain the PE/COFF Section information for the Standalone MM core module
- Status = GetStandaloneMmCorePeCoffSections (
- TeData,
- &ImageContext,
- &ImageBase,
- &SectionHeaderOffset,
- &NumberOfSections
- );
- if (EFI_ERROR (Status)) {
- goto finish;
- }
- //
- // ImageBase may deviate from ImageContext.ImageAddress if we are dealing
- // with a TE image, in which case the latter points to the actual offset
- // of the image, whereas ImageBase refers to the address where the image
- // would start if the stripped PE headers were still in place. In either
- // case, we need to fix up ImageBase so it refers to the actual current
- // load address.
- //
- ImageBase += (UINTN)TeData - ImageContext.ImageAddress;
- // Update the memory access permissions of individual sections in the
- // Standalone MM core module
- Status = UpdateMmFoundationPeCoffPermissions (
- &ImageContext,
- ImageBase,
- SectionHeaderOffset,
- NumberOfSections,
- ArmSetMemoryRegionNoExec,
- ArmSetMemoryRegionReadOnly,
- ArmClearMemoryRegionReadOnly
- );
- if (EFI_ERROR (Status)) {
- goto finish;
- }
- if (ImageContext.ImageAddress != (UINTN)TeData) {
- ImageContext.ImageAddress = (UINTN)TeData;
- ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB);
- ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB);
- Status = PeCoffLoaderRelocateImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
- }
- //
- // Create Hoblist based upon boot information passed by privileged software
- //
- HobStart = CreateHobListFromBootInfo (&CpuDriverEntryPoint, PayloadBootInfo);
- //
- // Call the MM Core entry point
- //
- ProcessModuleEntryPointList (HobStart);
- DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP %p\n", (VOID *) CpuDriverEntryPoint));
- finish:
- if (Status == RETURN_UNSUPPORTED) {
- Ret = -1;
- } else if (Status == RETURN_INVALID_PARAMETER) {
- Ret = -2;
- } else if (Status == EFI_NOT_FOUND) {
- Ret = -7;
- } else {
- Ret = 0;
- }
- ZeroMem (&InitMmFoundationSvcArgs, sizeof(InitMmFoundationSvcArgs));
- InitArmSvcArgs (&InitMmFoundationSvcArgs, &Ret);
- DelegatedEventLoop (&InitMmFoundationSvcArgs);
- }
|