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;
63 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
65 ASSERT (PhysicalAddressBits
<= 52);
66 if (PhysicalAddressBits
> 48) {
67 PhysicalAddressBits
= 48;
71 // Save the maximum support address in one global variable
73 mMmMemLibInternalMaximumSupportAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)(LShiftU64 (1, PhysicalAddressBits
) - 1);
74 DEBUG ((DEBUG_INFO
, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress
));
78 Initialize cached Mmram Ranges from HOB.
80 @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
81 @retval EFI_SUCCESS MmRanges are populated successfully.
85 MmMemLibInternalPopulateMmramRanges (
90 EFI_HOB_GUID_TYPE
*GuidHob
;
91 MM_CORE_DATA_HOB_DATA
*DataInHob
;
92 MM_CORE_PRIVATE_DATA
*MmCorePrivateData
;
93 EFI_HOB_GUID_TYPE
*MmramRangesHob
;
94 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK
*MmramRangesHobData
;
95 EFI_MMRAM_DESCRIPTOR
*MmramDescriptors
;
97 HobStart
= GetHobList ();
98 DEBUG ((DEBUG_INFO
, "%a - 0x%x\n", __FUNCTION__
, HobStart
));
101 // Extract MM Core Private context from the Hob. If absent search for
102 // a Hob containing the MMRAM ranges
104 GuidHob
= GetNextGuidHob (&gMmCoreDataHobGuid
, HobStart
);
105 if (GuidHob
== NULL
) {
106 MmramRangesHob
= GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid
);
107 if (MmramRangesHob
== NULL
) {
108 return EFI_UNSUPPORTED
;
111 MmramRangesHobData
= GET_GUID_HOB_DATA (MmramRangesHob
);
112 if ((MmramRangesHobData
== NULL
) || (MmramRangesHobData
->Descriptor
== NULL
)) {
113 return EFI_UNSUPPORTED
;
116 mMmMemLibInternalMmramCount
= MmramRangesHobData
->NumberOfMmReservedRegions
;
117 MmramDescriptors
= MmramRangesHobData
->Descriptor
;
119 DataInHob
= GET_GUID_HOB_DATA (GuidHob
);
120 if (DataInHob
== NULL
) {
121 return EFI_UNSUPPORTED
;
124 MmCorePrivateData
= (MM_CORE_PRIVATE_DATA
*)(UINTN
)DataInHob
->Address
;
125 if ((MmCorePrivateData
== NULL
) || (MmCorePrivateData
->MmramRanges
== 0)) {
126 return EFI_UNSUPPORTED
;
129 mMmMemLibInternalMmramCount
= (UINTN
)MmCorePrivateData
->MmramRangeCount
;
130 MmramDescriptors
= (EFI_MMRAM_DESCRIPTOR
*)(UINTN
)MmCorePrivateData
->MmramRanges
;
133 mMmMemLibInternalMmramRanges
= AllocatePool (mMmMemLibInternalMmramCount
* sizeof (EFI_MMRAM_DESCRIPTOR
));
134 if (mMmMemLibInternalMmramRanges
) {
136 mMmMemLibInternalMmramRanges
,
138 mMmMemLibInternalMmramCount
* sizeof (EFI_MMRAM_DESCRIPTOR
)
146 Deinitialize cached Mmram Ranges.
150 MmMemLibInternalFreeMmramRanges (
154 if (mMmMemLibInternalMmramRanges
!= NULL
) {
155 FreePool (mMmMemLibInternalMmramRanges
);