]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
MdeModulePkg/HiiDatabaseDxe: Fix the VS2010/VS2012 build fail
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / MemoryAttributesTable.c
CommitLineData
98c4b005
JY
1/** @file\r
2 UEFI MemoryAttributesTable support\r
3\r
4Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16#include <Library/BaseLib.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
20#include <Library/DxeServicesTableLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Library/UefiLib.h>\r
23\r
24#include <Guid/EventGroup.h>\r
25\r
26#include <Guid/MemoryAttributesTable.h>\r
27#include <Guid/PropertiesTable.h>\r
28\r
29#include "DxeMain.h"\r
30\r
31/**\r
32 This function for GetMemoryMap() with properties table capability.\r
33\r
34 It calls original GetMemoryMap() to get the original memory map information. Then\r
35 plus the additional memory map entries for PE Code/Data seperation.\r
36\r
37 @param MemoryMapSize A pointer to the size, in bytes, of the\r
38 MemoryMap buffer. On input, this is the size of\r
39 the buffer allocated by the caller. On output,\r
40 it is the size of the buffer returned by the\r
41 firmware if the buffer was large enough, or the\r
42 size of the buffer needed to contain the map if\r
43 the buffer was too small.\r
44 @param MemoryMap A pointer to the buffer in which firmware places\r
45 the current memory map.\r
46 @param MapKey A pointer to the location in which firmware\r
47 returns the key for the current memory map.\r
48 @param DescriptorSize A pointer to the location in which firmware\r
49 returns the size, in bytes, of an individual\r
50 EFI_MEMORY_DESCRIPTOR.\r
51 @param DescriptorVersion A pointer to the location in which firmware\r
52 returns the version number associated with the\r
53 EFI_MEMORY_DESCRIPTOR.\r
54\r
55 @retval EFI_SUCCESS The memory map was returned in the MemoryMap\r
56 buffer.\r
57 @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current\r
58 buffer size needed to hold the memory map is\r
59 returned in MemoryMapSize.\r
60 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
61\r
62**/\r
63EFI_STATUS\r
64EFIAPI\r
65CoreGetMemoryMapPropertiesTable (\r
66 IN OUT UINTN *MemoryMapSize,\r
67 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
68 OUT UINTN *MapKey,\r
69 OUT UINTN *DescriptorSize,\r
70 OUT UINT32 *DescriptorVersion\r
71 );\r
72\r
73extern EFI_PROPERTIES_TABLE mPropertiesTable;\r
74\r
98c4b005
JY
75/**\r
76 Install MemoryAttributesTable.\r
77\r
78 @param[in] Event The Event this notify function registered to.\r
79 @param[in] Context Pointer to the context data registered to the Event.\r
80**/\r
81VOID\r
82EFIAPI\r
83InstallMemoryAttributesTable (\r
84 EFI_EVENT Event,\r
85 VOID *Context\r
86 )\r
87{\r
88 UINTN MemoryMapSize;\r
89 EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
90 EFI_MEMORY_DESCRIPTOR *MemoryMapStart;\r
91 UINTN MapKey;\r
92 UINTN DescriptorSize;\r
93 UINT32 DescriptorVersion;\r
94 UINTN Index;\r
95 EFI_STATUS Status;\r
96 UINT32 RuntimeEntryCount;\r
97 EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;\r
98 EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry;\r
99\r
100 if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {\r
101 DEBUG ((EFI_D_VERBOSE, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, "));\r
102 DEBUG ((EFI_D_VERBOSE, "because Runtime Driver Section Alignment is not %dK.\n", EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT >> 10));\r
103 return ;\r
104 }\r
105\r
98c4b005
JY
106 MemoryMapSize = 0;\r
107 MemoryMap = NULL;\r
108 Status = CoreGetMemoryMapPropertiesTable (\r
109 &MemoryMapSize,\r
110 MemoryMap,\r
111 &MapKey,\r
112 &DescriptorSize,\r
113 &DescriptorVersion\r
114 );\r
115 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
116\r
117 do {\r
118 MemoryMap = AllocatePool (MemoryMapSize);\r
119 ASSERT (MemoryMap != NULL);\r
120\r
121 Status = CoreGetMemoryMapPropertiesTable (\r
122 &MemoryMapSize,\r
123 MemoryMap,\r
124 &MapKey,\r
125 &DescriptorSize,\r
126 &DescriptorVersion\r
127 );\r
128 if (EFI_ERROR (Status)) {\r
129 FreePool (MemoryMap);\r
130 }\r
131 } while (Status == EFI_BUFFER_TOO_SMALL);\r
132\r
133 MemoryMapStart = MemoryMap;\r
134 RuntimeEntryCount = 0;\r
135 for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {\r
136 switch (MemoryMap->Type) {\r
137 case EfiRuntimeServicesCode:\r
138 case EfiRuntimeServicesData:\r
139 RuntimeEntryCount ++;\r
140 break;\r
141 }\r
142 MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
143 }\r
144\r
145 //\r
146 // Allocate MemoryAttributesTable\r
147 //\r
148 MemoryAttributesTable = AllocatePool (sizeof(EFI_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount);\r
149 ASSERT (MemoryAttributesTable != NULL);\r
150 MemoryAttributesTable->Version = EFI_MEMORY_ATTRIBUTES_TABLE_VERSION;\r
151 MemoryAttributesTable->NumberOfEntries = RuntimeEntryCount;\r
152 MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize;\r
153 MemoryAttributesTable->Reserved = 0;\r
154 DEBUG ((EFI_D_VERBOSE, "MemoryAttributesTable:\n"));\r
155 DEBUG ((EFI_D_VERBOSE, " Version - 0x%08x\n", MemoryAttributesTable->Version));\r
156 DEBUG ((EFI_D_VERBOSE, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries));\r
157 DEBUG ((EFI_D_VERBOSE, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize));\r
158 MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1);\r
159 MemoryMap = MemoryMapStart;\r
160 for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {\r
161 switch (MemoryMap->Type) {\r
162 case EfiRuntimeServicesCode:\r
163 case EfiRuntimeServicesData:\r
164 CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize);\r
165 MemoryAttributesEntry->Attribute &= (EFI_MEMORY_RO|EFI_MEMORY_XP|EFI_MEMORY_RUNTIME);\r
166 DEBUG ((EFI_D_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry));\r
167 DEBUG ((EFI_D_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type));\r
168 DEBUG ((EFI_D_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart));\r
169 DEBUG ((EFI_D_VERBOSE, " VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart));\r
170 DEBUG ((EFI_D_VERBOSE, " NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages));\r
171 DEBUG ((EFI_D_VERBOSE, " Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute));\r
172 MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR(MemoryAttributesEntry, DescriptorSize);\r
173 break;\r
174 }\r
175 MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
176 }\r
177\r
178 Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, MemoryAttributesTable);\r
179 ASSERT_EFI_ERROR (Status);\r
98c4b005
JY
180}\r
181\r
182/**\r
183 Initialize MemoryAttrubutesTable support.\r
184**/\r
185VOID\r
186EFIAPI\r
187CoreInitializeMemoryAttributesTable (\r
188 VOID\r
189 )\r
190{\r
191 EFI_STATUS Status;\r
192 EFI_EVENT ReadyToBootEvent;\r
193\r
194 //\r
195 // Construct the table at ReadyToBoot, because this should be\r
196 // last point to allocate RuntimeCode/RuntimeData.\r
197 //\r
198 Status = gBS->CreateEventEx (\r
199 EVT_NOTIFY_SIGNAL,\r
200 TPL_NOTIFY,\r
201 InstallMemoryAttributesTable,\r
202 NULL,\r
203 &gEfiEventReadyToBootGuid,\r
204 &ReadyToBootEvent\r
205 );\r
206 ASSERT_EFI_ERROR (Status);\r
207 return ;\r
208}\r