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
ValidateMemoryTypeInfoVariable(IN EFI_MEMORY_TYPE_INFORMATION * MemoryData,IN UINTN MemoryDataSize)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
PeimInitializeWinNtAutoScan(IN EFI_PEI_FILE_HANDLE FileHandle,IN CONST EFI_PEI_SERVICES ** PeiServices)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