1 /** @file 2 3 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> 4 SPDX-License-Identifier: BSD-2-Clause-Patent 5 6 **/ 7 8 #include <Uefi.h> 9 #include <PiDxe.h> 10 #include <Library/UefiBootServicesTableLib.h> 11 #include <Library/TestPointCheckLib.h> 12 #include <Library/TestPointLib.h> 13 #include <Library/DebugLib.h> 14 #include <Library/PrintLib.h> 15 #include <Library/UefiLib.h> 16 #include <Library/BaseMemoryLib.h> 17 #include <Library/MemoryAllocationLib.h> 18 19 CHAR8 *mMemoryTypeShortName[] = { 20 "Reserved ", 21 "LoaderCode", 22 "LoaderData", 23 "BS_Code ", 24 "BS_Data ", 25 "RT_Code ", 26 "RT_Data ", 27 "Available ", 28 "Unusable ", 29 "ACPI_Recl ", 30 "ACPI_NVS ", 31 "MMIO ", 32 "MMIO_Port ", 33 "PalCode ", 34 "Persistent", 35 }; 36 37 STATIC CHAR8 mUnknownStr[11]; 38 39 CHAR8 * 40 ShortNameOfMemoryType( 41 IN UINT32 Type 42 ) 43 { 44 if (Type < sizeof(mMemoryTypeShortName) / sizeof(mMemoryTypeShortName[0])) { 45 return mMemoryTypeShortName[Type]; 46 } else { 47 AsciiSPrint(mUnknownStr, sizeof(mUnknownStr), "[%08x]", Type); 48 return mUnknownStr; 49 } 50 } 51 52 53 /** 54 Dump memory map. 55 56 @param MemoryMap A pointer to the buffer in which firmware places 57 the current memory map. 58 @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. 59 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. 60 **/ 61 VOID 62 TestPointDumpMemoryMap ( 63 IN EFI_MEMORY_DESCRIPTOR *MemoryMap, 64 IN UINTN MemoryMapSize, 65 IN UINTN DescriptorSize 66 ) 67 { 68 EFI_MEMORY_DESCRIPTOR *Entry; 69 UINTN NumberOfEntries; 70 UINTN Index; 71 UINT64 Pages[EfiMaxMemoryType]; 72 73 ZeroMem (Pages, sizeof(Pages)); 74 75 DEBUG ((EFI_D_INFO, "MemoryMap:\n")); 76 77 Entry = MemoryMap; 78 NumberOfEntries = MemoryMapSize / DescriptorSize; 79 DEBUG ((DEBUG_INFO, "Type Start End # Pages Attributes\n")); 80 for (Index = 0; Index < NumberOfEntries; Index++) { 81 DEBUG ((DEBUG_INFO, ShortNameOfMemoryType(Entry->Type))); 82 DEBUG ((DEBUG_INFO, " %016LX-%016LX %016LX %016LX\n", 83 Entry->PhysicalStart, 84 Entry->PhysicalStart+MultU64x64 (SIZE_4KB,Entry->NumberOfPages) - 1, 85 Entry->NumberOfPages, 86 Entry->Attribute 87 )); 88 if (Entry->Type < EfiMaxMemoryType) { 89 Pages[Entry->Type] += Entry->NumberOfPages; 90 } 91 Entry = NEXT_MEMORY_DESCRIPTOR (Entry, DescriptorSize); 92 } 93 94 DEBUG ((DEBUG_INFO, "\n")); 95 DEBUG ((DEBUG_INFO, " Reserved : %14ld Pages (%ld Bytes)\n", Pages[EfiReservedMemoryType], MultU64x64(SIZE_4KB, Pages[EfiReservedMemoryType]))); 96 DEBUG ((DEBUG_INFO, " LoaderCode: %14ld Pages (%ld Bytes)\n", Pages[EfiLoaderCode], MultU64x64(SIZE_4KB, Pages[EfiLoaderCode]))); 97 DEBUG ((DEBUG_INFO, " LoaderData: %14ld Pages (%ld Bytes)\n", Pages[EfiLoaderData], MultU64x64(SIZE_4KB, Pages[EfiLoaderData]))); 98 DEBUG ((DEBUG_INFO, " BS_Code : %14ld Pages (%ld Bytes)\n", Pages[EfiBootServicesCode], MultU64x64(SIZE_4KB, Pages[EfiBootServicesCode]))); 99 DEBUG ((DEBUG_INFO, " BS_Data : %14ld Pages (%ld Bytes)\n", Pages[EfiBootServicesData], MultU64x64(SIZE_4KB, Pages[EfiBootServicesData]))); 100 DEBUG ((DEBUG_INFO, " RT_Code : %14ld Pages (%ld Bytes)\n", Pages[EfiRuntimeServicesCode], MultU64x64(SIZE_4KB, Pages[EfiRuntimeServicesCode]))); 101 DEBUG ((DEBUG_INFO, " RT_Data : %14ld Pages (%ld Bytes)\n", Pages[EfiRuntimeServicesData], MultU64x64(SIZE_4KB, Pages[EfiRuntimeServicesData]))); 102 DEBUG ((DEBUG_INFO, " ACPI_Recl : %14ld Pages (%ld Bytes)\n", Pages[EfiACPIReclaimMemory], MultU64x64(SIZE_4KB, Pages[EfiACPIReclaimMemory]))); 103 DEBUG ((DEBUG_INFO, " ACPI_NVS : %14ld Pages (%ld Bytes)\n", Pages[EfiACPIMemoryNVS], MultU64x64(SIZE_4KB, Pages[EfiACPIMemoryNVS]))); 104 DEBUG ((DEBUG_INFO, " MMIO : %14ld Pages (%ld Bytes)\n", Pages[EfiMemoryMappedIO], MultU64x64(SIZE_4KB, Pages[EfiMemoryMappedIO]))); 105 DEBUG ((DEBUG_INFO, " MMIO_Port : %14ld Pages (%ld Bytes)\n", Pages[EfiMemoryMappedIOPortSpace], MultU64x64(SIZE_4KB, Pages[EfiMemoryMappedIOPortSpace]))); 106 DEBUG ((DEBUG_INFO, " PalCode : %14ld Pages (%ld Bytes)\n", Pages[EfiPalCode], MultU64x64(SIZE_4KB, Pages[EfiPalCode]))); 107 DEBUG ((DEBUG_INFO, " Available : %14ld Pages (%ld Bytes)\n", Pages[EfiConventionalMemory], MultU64x64(SIZE_4KB, Pages[EfiConventionalMemory]))); 108 DEBUG ((DEBUG_INFO, " Persistent: %14ld Pages (%ld Bytes)\n", Pages[EfiPersistentMemory], MultU64x64(SIZE_4KB, Pages[EfiPersistentMemory]))); 109 DEBUG ((DEBUG_INFO, " -------------- \n")); 110 } 111 112 BOOLEAN 113 TestPointCheckUefiMemoryMapEntry ( 114 IN EFI_MEMORY_DESCRIPTOR *MemoryMap, 115 IN UINTN MemoryMapSize, 116 IN UINTN DescriptorSize 117 ) 118 { 119 EFI_MEMORY_DESCRIPTOR *Entry; 120 UINTN NumberOfEntries; 121 UINTN Index; 122 UINT64 EntryCount[EfiMaxMemoryType]; 123 124 ZeroMem (EntryCount, sizeof(EntryCount)); 125 126 Entry = MemoryMap; 127 NumberOfEntries = MemoryMapSize / DescriptorSize; 128 for (Index = 0; Index < NumberOfEntries; Index++) { 129 if (Entry->Type < EfiMaxMemoryType) { 130 EntryCount[Entry->Type] ++; 131 } 132 Entry = NEXT_MEMORY_DESCRIPTOR (Entry, DescriptorSize); 133 } 134 if (EntryCount[EfiRuntimeServicesCode] > 1) { 135 DEBUG ((DEBUG_ERROR, "EfiRuntimeServicesCode entry - %d\n", EntryCount[EfiRuntimeServicesCode])); 136 } 137 if (EntryCount[EfiRuntimeServicesData] > 1) { 138 DEBUG ((DEBUG_ERROR, "EfiRuntimeServicesData entry - %d\n", EntryCount[EfiRuntimeServicesCode])); 139 } 140 if (EntryCount[EfiACPIMemoryNVS] > 1) { 141 DEBUG ((DEBUG_ERROR, "EfiACPIMemoryNVS entry - %d\n", EntryCount[EfiACPIMemoryNVS])); 142 } 143 if (EntryCount[EfiACPIReclaimMemory] > 1) { 144 DEBUG ((DEBUG_ERROR, "EfiACPIReclaimMemory entry - %d\n", EntryCount[EfiACPIReclaimMemory])); 145 } 146 if ((EntryCount[EfiRuntimeServicesCode] > 1) || 147 (EntryCount[EfiRuntimeServicesData] > 1) || 148 (EntryCount[EfiACPIReclaimMemory] > 1) || 149 (EntryCount[EfiACPIMemoryNVS] > 1) ) { 150 return FALSE; 151 } else { 152 return TRUE; 153 } 154 } 155 156 VOID 157 TestPointDumpUefiMemoryMap ( 158 OUT EFI_MEMORY_DESCRIPTOR **UefiMemoryMap, OPTIONAL 159 OUT UINTN *UefiMemoryMapSize, OPTIONAL 160 OUT UINTN *UefiDescriptorSize, OPTIONAL 161 IN BOOLEAN DumpPrint 162 ) 163 { 164 EFI_STATUS Status; 165 UINTN MapKey; 166 UINT32 DescriptorVersion; 167 EFI_MEMORY_DESCRIPTOR *MemoryMap; 168 UINTN MemoryMapSize; 169 UINTN DescriptorSize; 170 171 if (UefiMemoryMap != NULL) { 172 *UefiMemoryMap = NULL; 173 *UefiMemoryMapSize = 0; 174 *UefiDescriptorSize = 0; 175 } 176 177 if (DumpPrint) { 178 DEBUG ((DEBUG_INFO, "==== TestPointDumpUefiMemoryMap - Enter\n")); 179 } 180 MemoryMapSize = 0; 181 MemoryMap = NULL; 182 Status = gBS->GetMemoryMap ( 183 &MemoryMapSize, 184 MemoryMap, 185 &MapKey, 186 &DescriptorSize, 187 &DescriptorVersion 188 ); 189 ASSERT (Status == EFI_BUFFER_TOO_SMALL); 190 191 do { 192 Status = gBS->AllocatePool (EfiBootServicesData, MemoryMapSize, (VOID **)&MemoryMap); 193 ASSERT (MemoryMap != NULL); 194 if (MemoryMap == NULL) { 195 goto Done ; 196 } 197 198 Status = gBS->GetMemoryMap ( 199 &MemoryMapSize, 200 MemoryMap, 201 &MapKey, 202 &DescriptorSize, 203 &DescriptorVersion 204 ); 205 if (EFI_ERROR (Status)) { 206 gBS->FreePool (MemoryMap); 207 MemoryMap = NULL; 208 } 209 } while (Status == EFI_BUFFER_TOO_SMALL); 210 211 if (MemoryMap == NULL) { 212 goto Done ; 213 } 214 215 if (DumpPrint) { 216 TestPointDumpMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize); 217 } 218 219 if (UefiMemoryMap != NULL) { 220 *UefiMemoryMap = AllocateCopyPool (MemoryMapSize, MemoryMap); 221 *UefiMemoryMapSize = MemoryMapSize; 222 *UefiDescriptorSize = DescriptorSize; 223 } 224 gBS->FreePool (MemoryMap); 225 226 Done: 227 if (DumpPrint) { 228 DEBUG ((DEBUG_INFO, "==== TestPointDumpUefiMemoryMap - Exit\n")); 229 } 230 return ; 231 } 232 233 EFI_STATUS 234 TestPointCheckUefiMemoryMap ( 235 VOID 236 ) 237 { 238 EFI_STATUS Status; 239 UINTN MapKey; 240 UINT32 DescriptorVersion; 241 EFI_MEMORY_DESCRIPTOR *MemoryMap; 242 UINTN UefiMemoryMapSize; 243 UINTN UefiDescriptorSize; 244 BOOLEAN Result; 245 246 DEBUG ((DEBUG_INFO, "==== TestPointCheckUefiMemoryMap - Enter\n")); 247 UefiMemoryMapSize = 0; 248 MemoryMap = NULL; 249 Status = gBS->GetMemoryMap ( 250 &UefiMemoryMapSize, 251 MemoryMap, 252 &MapKey, 253 &UefiDescriptorSize, 254 &DescriptorVersion 255 ); 256 ASSERT (Status == EFI_BUFFER_TOO_SMALL); 257 258 do { 259 Status = gBS->AllocatePool (EfiBootServicesData, UefiMemoryMapSize, (VOID **)&MemoryMap); 260 ASSERT (MemoryMap != NULL); 261 if (MemoryMap == NULL) { 262 Status = EFI_OUT_OF_RESOURCES; 263 goto Done ; 264 } 265 266 Status = gBS->GetMemoryMap ( 267 &UefiMemoryMapSize, 268 MemoryMap, 269 &MapKey, 270 &UefiDescriptorSize, 271 &DescriptorVersion 272 ); 273 if (EFI_ERROR (Status)) { 274 gBS->FreePool (MemoryMap); 275 MemoryMap = NULL; 276 } 277 } while (Status == EFI_BUFFER_TOO_SMALL); 278 279 if (MemoryMap == NULL) { 280 Status = EFI_OUT_OF_RESOURCES; 281 goto Done ; 282 } 283 284 Result = TestPointCheckUefiMemoryMapEntry (MemoryMap, UefiMemoryMapSize, UefiDescriptorSize); 285 if (!Result) { 286 TestPointLibAppendErrorString ( 287 PLATFORM_TEST_POINT_ROLE_PLATFORM_IBV, 288 NULL, 289 TEST_POINT_BYTE4_READY_TO_BOOT_MEMORY_TYPE_INFORMATION_FUNCTIONAL_ERROR_CODE \ 290 TEST_POINT_READY_TO_BOOT \ 291 TEST_POINT_BYTE4_READY_TO_BOOT_MEMORY_TYPE_INFORMATION_FUNCTIONAL_ERROR_STRING 292 ); 293 Status = EFI_INVALID_PARAMETER; 294 } else { 295 Status = EFI_SUCCESS; 296 } 297 298 gBS->FreePool (MemoryMap); 299 300 Done: 301 DEBUG ((DEBUG_INFO, "==== TestPointCheckUefiMemoryMap - Exit\n")); 302 return Status; 303 }