2 Internal ARCH Specific file of MM memory check library.
4 MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL
5 to get MMRAM information. In order to use this library instance, the platform should produce
6 all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core
7 and MM driver) and/or specific dedicated hardware.
9 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
10 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
11 Copyright (c) Microsoft Corporation.
13 SPDX-License-Identifier: BSD-2-Clause-Patent
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/HobLib.h>
23 #include <Guid/MmCoreData.h>
24 #include <Guid/MmramMemoryReserve.h>
27 // Maximum support address used to check input buffer
29 extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress
;
30 extern EFI_MMRAM_DESCRIPTOR
*mMmMemLibInternalMmramRanges
;
31 extern UINTN mMmMemLibInternalMmramCount
;
34 Calculate and save the maximum support address.
38 MmMemLibInternalCalculateMaximumSupportAddress (
44 UINT8 PhysicalAddressBits
;
47 // Get physical address bits supported.
49 Hob
= GetFirstHob (EFI_HOB_TYPE_CPU
);
51 PhysicalAddressBits
= ((EFI_HOB_CPU
*) Hob
)->SizeOfMemorySpace
;
53 AsmCpuid (0x80000000, &RegEax
, NULL
, NULL
, NULL
);
54 if (RegEax
>= 0x80000008) {
55 AsmCpuid (0x80000008, &RegEax
, NULL
, NULL
, NULL
);
56 PhysicalAddressBits
= (UINT8
) RegEax
;
58 PhysicalAddressBits
= 36;
62 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
64 ASSERT (PhysicalAddressBits
<= 52);
65 if (PhysicalAddressBits
> 48) {
66 PhysicalAddressBits
= 48;
70 // Save the maximum support address in one global variable
72 mMmMemLibInternalMaximumSupportAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)(LShiftU64 (1, PhysicalAddressBits
) - 1);
73 DEBUG ((DEBUG_INFO
, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress
));
77 Initialize cached Mmram Ranges from HOB.
79 @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
80 @retval EFI_SUCCESS MmRanges are populated successfully.
84 MmMemLibInternalPopulateMmramRanges (
89 EFI_HOB_GUID_TYPE
*GuidHob
;
90 MM_CORE_DATA_HOB_DATA
*DataInHob
;
91 MM_CORE_PRIVATE_DATA
*MmCorePrivateData
;
92 EFI_HOB_GUID_TYPE
*MmramRangesHob
;
93 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK
*MmramRangesHobData
;
94 EFI_MMRAM_DESCRIPTOR
*MmramDescriptors
;
96 HobStart
= GetHobList ();
97 DEBUG ((DEBUG_INFO
, "%a - 0x%x\n", __FUNCTION__
, HobStart
));
100 // Extract MM Core Private context from the Hob. If absent search for
101 // a Hob containing the MMRAM ranges
103 GuidHob
= GetNextGuidHob (&gMmCoreDataHobGuid
, HobStart
);
104 if (GuidHob
== NULL
) {
105 MmramRangesHob
= GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid
);
106 if (MmramRangesHob
== NULL
) {
107 return EFI_UNSUPPORTED
;
110 MmramRangesHobData
= GET_GUID_HOB_DATA (MmramRangesHob
);
111 if (MmramRangesHobData
== NULL
|| MmramRangesHobData
->Descriptor
== NULL
) {
112 return EFI_UNSUPPORTED
;
115 mMmMemLibInternalMmramCount
= MmramRangesHobData
->NumberOfMmReservedRegions
;
116 MmramDescriptors
= MmramRangesHobData
->Descriptor
;
118 DataInHob
= GET_GUID_HOB_DATA (GuidHob
);
119 if (DataInHob
== NULL
) {
120 return EFI_UNSUPPORTED
;
123 MmCorePrivateData
= (MM_CORE_PRIVATE_DATA
*) (UINTN
) DataInHob
->Address
;
124 if (MmCorePrivateData
== NULL
|| MmCorePrivateData
->MmramRanges
== 0) {
125 return EFI_UNSUPPORTED
;
128 mMmMemLibInternalMmramCount
= (UINTN
) MmCorePrivateData
->MmramRangeCount
;
129 MmramDescriptors
= (EFI_MMRAM_DESCRIPTOR
*) (UINTN
) MmCorePrivateData
->MmramRanges
;
132 mMmMemLibInternalMmramRanges
= AllocatePool (mMmMemLibInternalMmramCount
* sizeof (EFI_MMRAM_DESCRIPTOR
));
133 if (mMmMemLibInternalMmramRanges
) {
134 CopyMem (mMmMemLibInternalMmramRanges
,
136 mMmMemLibInternalMmramCount
* sizeof (EFI_MMRAM_DESCRIPTOR
));
143 Deinitialize cached Mmram Ranges.
147 MmMemLibInternalFreeMmramRanges (
151 if (mMmMemLibInternalMmramRanges
!= NULL
) {
152 FreePool (mMmMemLibInternalMmramRanges
);