1 /**@file 2 3 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> 4 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 Module Name: 14 WinNtAutoscan.c 15 16 Abstract: 17 This PEIM to abstract memory auto-scan in a Windows NT environment. 18 19 Revision History 20 21 **/ 22 23 // 24 // The package level header files this module uses 25 // 26 #include <PiPei.h> 27 #include <WinNtPeim.h> 28 // 29 // The protocols, PPI and GUID defintions for this module 30 // 31 #include <Ppi/NtAutoscan.h> 32 #include <Ppi/ReadOnlyVariable2.h> 33 34 #include <Guid/MemoryTypeInformation.h> 35 36 // 37 // The Library classes this module consumes 38 // 39 #include <Library/DebugLib.h> 40 #include <Library/PeimEntryPoint.h> 41 #include <Library/HobLib.h> 42 #include <Library/PeiServicesLib.h> 43 44 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { 45 { EfiReservedMemoryType, 0x0004 }, 46 { EfiRuntimeServicesCode, 0x0040 }, 47 { EfiRuntimeServicesData, 0x0040 }, 48 { EfiBootServicesCode, 0x0300 }, 49 { EfiBootServicesData, 0x1000 }, 50 { EfiMaxMemoryType, 0 } 51 }; 52 53 /** 54 Validate variable data for the MemoryTypeInformation. 55 56 @param MemoryData Variable data. 57 @param MemoryDataSize Variable data length. 58 59 @return TRUE The variable data is valid. 60 @return FALSE The variable data is invalid. 61 62 **/ 63 BOOLEAN 64 ValidateMemoryTypeInfoVariable ( 65 IN EFI_MEMORY_TYPE_INFORMATION *MemoryData, 66 IN UINTN MemoryDataSize 67 ) 68 { 69 UINTN Count; 70 UINTN Index; 71 72 // Check the input parameter. 73 if (MemoryData == NULL) { 74 return FALSE; 75 } 76 77 // Get Count 78 Count = MemoryDataSize / sizeof (*MemoryData); 79 80 // Check Size 81 if (Count * sizeof(*MemoryData) != MemoryDataSize) { 82 return FALSE; 83 } 84 85 // Check last entry type filed. 86 if (MemoryData[Count - 1].Type != EfiMaxMemoryType) { 87 return FALSE; 88 } 89 90 // Check the type filed. 91 for (Index = 0; Index < Count - 1; Index++) { 92 if (MemoryData[Index].Type >= EfiMaxMemoryType) { 93 return FALSE; 94 } 95 } 96 97 return TRUE; 98 } 99 100 EFI_STATUS 101 EFIAPI 102 PeimInitializeWinNtAutoScan ( 103 IN EFI_PEI_FILE_HANDLE FileHandle, 104 IN CONST EFI_PEI_SERVICES **PeiServices 105 ) 106 /*++ 107 108 Routine Description: 109 Perform a call-back into the SEC simulator to get a memory value 110 111 Arguments: 112 FfsHeader - General purpose data available to every PEIM 113 PeiServices - General purpose services available to every PEIM. 114 115 Returns: 116 None 117 118 --*/ 119 { 120 EFI_STATUS Status; 121 EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; 122 PEI_NT_AUTOSCAN_PPI *PeiNtService; 123 UINT64 MemorySize; 124 EFI_PHYSICAL_ADDRESS MemoryBase; 125 UINTN Index; 126 EFI_RESOURCE_ATTRIBUTE_TYPE Attributes; 127 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; 128 UINTN DataSize; 129 EFI_MEMORY_TYPE_INFORMATION MemoryData [EfiMaxMemoryType + 1]; 130 131 132 DEBUG ((EFI_D_ERROR, "NT 32 Autoscan PEIM Loaded\n")); 133 134 // 135 // Get the PEI NT Autoscan PPI 136 // 137 Status = PeiServicesLocatePpi ( 138 &gPeiNtAutoScanPpiGuid, // GUID 139 0, // INSTANCE 140 &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR 141 (VOID**)&PeiNtService // PPI 142 ); 143 ASSERT_EFI_ERROR (Status); 144 145 Index = 0; 146 do { 147 Status = PeiNtService->NtAutoScan (Index, &MemoryBase, &MemorySize); 148 if (!EFI_ERROR (Status)) { 149 Attributes = 150 ( 151 EFI_RESOURCE_ATTRIBUTE_PRESENT | 152 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 153 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | 154 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | 155 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | 156 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 157 ); 158 159 if (Index == 0) { 160 // 161 // Register the memory with the PEI Core 162 // 163 Status = PeiServicesInstallPeiMemory (MemoryBase, MemorySize); 164 ASSERT_EFI_ERROR (Status); 165 166 Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED; 167 } 168 169 BuildResourceDescriptorHob ( 170 EFI_RESOURCE_SYSTEM_MEMORY, 171 Attributes, 172 MemoryBase, 173 MemorySize 174 ); 175 } 176 Index++; 177 } while (!EFI_ERROR (Status)); 178 179 // 180 // Build the CPU hob with 52-bit addressing and 16-bits of IO space. 181 // 182 BuildCpuHob (52, 16); 183 184 // 185 // Build GUIDed Hob that contains the Memory Type Information array 186 // 187 Status = PeiServicesLocatePpi ( 188 &gEfiPeiReadOnlyVariable2PpiGuid, 189 0, 190 NULL, 191 (VOID **)&Variable 192 ); 193 ASSERT_EFI_ERROR (Status); 194 195 DataSize = sizeof (MemoryData); 196 Status = Variable->GetVariable ( 197 Variable, 198 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, 199 &gEfiMemoryTypeInformationGuid, 200 NULL, 201 &DataSize, 202 &MemoryData 203 ); 204 if (EFI_ERROR (Status) || !ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) { 205 // 206 // Create Memory Type Information HOB 207 // 208 BuildGuidDataHob ( 209 &gEfiMemoryTypeInformationGuid, 210 mDefaultMemoryTypeInformation, 211 sizeof(mDefaultMemoryTypeInformation) 212 ); 213 } else { 214 // 215 // Create Memory Type Information HOB 216 // 217 BuildGuidDataHob ( 218 &gEfiMemoryTypeInformationGuid, 219 MemoryData, 220 DataSize 221 ); 222 } 223 224 return Status; 225 } 226