]> git.proxmox.com Git - mirror_edk2.git/blob - StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
1a978541716af3ac4fae48a1988478d30b9bfe0e
[mirror_edk2.git] / StandaloneMmPkg / Library / StandaloneMmMemLib / X86StandaloneMmMemLibInternal.c
1 /** @file
2 Internal ARCH Specific file of MM memory check library.
3
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.
8
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.
12
13 SPDX-License-Identifier: BSD-2-Clause-Patent
14
15 **/
16 #include <PiMm.h>
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>
22
23 #include <Guid/MmCoreData.h>
24 #include <Guid/MmramMemoryReserve.h>
25
26 //
27 // Maximum support address used to check input buffer
28 //
29 extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;
30 extern EFI_MMRAM_DESCRIPTOR *mMmMemLibInternalMmramRanges;
31 extern UINTN mMmMemLibInternalMmramCount;
32
33 /**
34 Calculate and save the maximum support address.
35
36 **/
37 VOID
38 MmMemLibInternalCalculateMaximumSupportAddress (
39 VOID
40 )
41 {
42 VOID *Hob;
43 UINT32 RegEax;
44 UINT8 PhysicalAddressBits;
45
46 //
47 // Get physical address bits supported.
48 //
49 Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
50 if (Hob != NULL) {
51 PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
52 } else {
53 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
54 if (RegEax >= 0x80000008) {
55 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
56 PhysicalAddressBits = (UINT8) RegEax;
57 } else {
58 PhysicalAddressBits = 36;
59 }
60 }
61 //
62 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
63 //
64 ASSERT (PhysicalAddressBits <= 52);
65 if (PhysicalAddressBits > 48) {
66 PhysicalAddressBits = 48;
67 }
68
69 //
70 // Save the maximum support address in one global variable
71 //
72 mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);
73 DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));
74 }
75
76 /**
77 Initialize cached Mmram Ranges from HOB.
78
79 @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
80 @retval EFI_SUCCESS MmRanges are populated successfully.
81
82 **/
83 EFI_STATUS
84 MmMemLibInternalPopulateMmramRanges (
85 VOID
86 )
87 {
88 VOID *HobStart;
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;
95
96 HobStart = GetHobList ();
97 DEBUG ((DEBUG_INFO, "%a - 0x%x\n", __FUNCTION__, HobStart));
98
99 //
100 // Extract MM Core Private context from the Hob. If absent search for
101 // a Hob containing the MMRAM ranges
102 //
103 GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);
104 if (GuidHob == NULL) {
105 MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid);
106 if (MmramRangesHob == NULL) {
107 return EFI_UNSUPPORTED;
108 }
109
110 MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
111 if (MmramRangesHobData == NULL || MmramRangesHobData->Descriptor == NULL) {
112 return EFI_UNSUPPORTED;
113 }
114
115 mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions;
116 MmramDescriptors = MmramRangesHobData->Descriptor;
117 } else {
118 DataInHob = GET_GUID_HOB_DATA (GuidHob);
119 if (DataInHob == NULL) {
120 return EFI_UNSUPPORTED;
121 }
122
123 MmCorePrivateData = (MM_CORE_PRIVATE_DATA *) (UINTN) DataInHob->Address;
124 if (MmCorePrivateData == NULL || MmCorePrivateData->MmramRanges == 0) {
125 return EFI_UNSUPPORTED;
126 }
127
128 mMmMemLibInternalMmramCount = (UINTN) MmCorePrivateData->MmramRangeCount;
129 MmramDescriptors = (EFI_MMRAM_DESCRIPTOR *) (UINTN) MmCorePrivateData->MmramRanges;
130 }
131
132 mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));
133 if (mMmMemLibInternalMmramRanges) {
134 CopyMem (mMmMemLibInternalMmramRanges,
135 MmramDescriptors,
136 mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));
137 }
138
139 return EFI_SUCCESS;
140 }
141
142 /**
143 Deinitialize cached Mmram Ranges.
144
145 **/
146 VOID
147 MmMemLibInternalFreeMmramRanges (
148 VOID
149 )
150 {
151 if (mMmMemLibInternalMmramRanges != NULL) {
152 FreePool (mMmMemLibInternalMmramRanges);
153 }
154 }
155