/** @file Internal ARCH Specific file of MM memory check library. MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL to get MMRAM information. In order to use this library instance, the platform should produce all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core and MM driver) and/or specific dedicated hardware. Copyright (c) 2015, Intel Corporation. All rights reserved.
Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include // // Maximum support address used to check input buffer // extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress; extern EFI_MMRAM_DESCRIPTOR *mMmMemLibInternalMmramRanges; extern UINTN mMmMemLibInternalMmramCount; /** Calculate and save the maximum support address. **/ VOID MmMemLibInternalCalculateMaximumSupportAddress ( VOID ) { VOID *Hob; UINT32 RegEax; UINT8 PhysicalAddressBits; // // Get physical address bits supported. // Hob = GetFirstHob (EFI_HOB_TYPE_CPU); if (Hob != NULL) { PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace; } else { AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); if (RegEax >= 0x80000008) { AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); PhysicalAddressBits = (UINT8)RegEax; } else { PhysicalAddressBits = 36; } } // // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses. // ASSERT (PhysicalAddressBits <= 52); if (PhysicalAddressBits > 48) { PhysicalAddressBits = 48; } // // Save the maximum support address in one global variable // mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1); DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress)); } /** Initialize cached Mmram Ranges from HOB. @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information. @retval EFI_SUCCESS MmRanges are populated successfully. **/ EFI_STATUS MmMemLibInternalPopulateMmramRanges ( VOID ) { VOID *HobStart; EFI_HOB_GUID_TYPE *GuidHob; MM_CORE_DATA_HOB_DATA *DataInHob; MM_CORE_PRIVATE_DATA *MmCorePrivateData; EFI_HOB_GUID_TYPE *MmramRangesHob; EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData; EFI_MMRAM_DESCRIPTOR *MmramDescriptors; HobStart = GetHobList (); DEBUG ((DEBUG_INFO, "%a - 0x%x\n", __func__, HobStart)); // // Extract MM Core Private context from the Hob. If absent search for // a Hob containing the MMRAM ranges // GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart); if (GuidHob == NULL) { MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid); if (MmramRangesHob == NULL) { return EFI_UNSUPPORTED; } MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); if ((MmramRangesHobData == NULL) || (MmramRangesHobData->Descriptor == NULL)) { return EFI_UNSUPPORTED; } mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions; MmramDescriptors = MmramRangesHobData->Descriptor; } else { DataInHob = GET_GUID_HOB_DATA (GuidHob); if (DataInHob == NULL) { return EFI_UNSUPPORTED; } MmCorePrivateData = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address; if ((MmCorePrivateData == NULL) || (MmCorePrivateData->MmramRanges == 0)) { return EFI_UNSUPPORTED; } mMmMemLibInternalMmramCount = (UINTN)MmCorePrivateData->MmramRangeCount; MmramDescriptors = (EFI_MMRAM_DESCRIPTOR *)(UINTN)MmCorePrivateData->MmramRanges; } mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR)); if (mMmMemLibInternalMmramRanges) { CopyMem ( mMmMemLibInternalMmramRanges, MmramDescriptors, mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR) ); } return EFI_SUCCESS; } /** Deinitialize cached Mmram Ranges. **/ VOID MmMemLibInternalFreeMmramRanges ( VOID ) { if (mMmMemLibInternalMmramRanges != NULL) { FreePool (mMmMemLibInternalMmramRanges); } }