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