1 /** @file
2
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
4
5
6 This program and the accompanying materials are licensed and made available under
7
8 the terms and conditions of the BSD License that accompanies this distribution.
9
10 The full text of the license may be found at
11
12 http://opensource.org/licenses/bsd-license.php.
13
14
15
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19
20
21
22
23
24 Module Name:
25
26 IchS3Save.c
27
28 Abstract:
29
30 SMM S3 handler Driver implementation file
31
InitRuntimeScriptTable(IN EFI_SYSTEM_TABLE * SystemTable)32 Revision History
33
34 **/
35 #include "SmmPlatform.h"
36
37 extern UINT16 mAcpiBaseAddr;
38 EFI_PHYSICAL_ADDRESS mRuntimeScriptTableBase;
39
40 EFI_STATUS
41 InitRuntimeScriptTable (
42 IN EFI_SYSTEM_TABLE *SystemTable
43 )
44 {
45 EFI_STATUS Status;
46 UINT32 VarAttrib;
47 UINTN VarSize;
48 ACPI_VARIABLE_SET_COMPATIBILITY *AcpiVariableBase;
49
50 //
51 // Allocate runtime ACPI script table space. We need it to save some
52 // settings done by CSM, which runs after normal script table closed
53 //
54 Status = gBS->AllocatePages (
55 AllocateAnyPages,
56 EfiACPIReclaimMemory,
57 1,
58 &mRuntimeScriptTableBase
59 );
60 if (EFI_ERROR(Status)) {
61 return EFI_OUT_OF_RESOURCES ;
62 }
63
64 //
65 // Save runtime script table base into global ACPI variable
66 //
67 VarAttrib = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
68 | EFI_VARIABLE_NON_VOLATILE;
69 VarSize = sizeof (UINTN);
70 Status = SystemTable->RuntimeServices->GetVariable (
71 ACPI_GLOBAL_VARIABLE,
72 &gEfiAcpiVariableCompatiblityGuid,
73 &VarAttrib,
74 &VarSize,
75 &AcpiVariableBase
76 );
77 if (EFI_ERROR(Status)) {
SaveRuntimeScriptTable(VOID)78 return Status;
79 }
80
81 AcpiVariableBase->RuntimeScriptTableBase = mRuntimeScriptTableBase;
82
83 return EFI_SUCCESS;
84 }
85
86 EFI_STATUS
87 SaveRuntimeScriptTable (
88 VOID
89 )
90 {
91 SMM_PCI_IO_ADDRESS PciAddress;
92 UINT32 Data32;
93 UINT16 Data16;
94 UINT8 Data8;
95 UINT8 Mask;
96 UINTN Index;
97 UINTN Offset;
98 UINT8 RegTable[] = {
99
100 //
101 //Bus , Dev, Func, DMI
102 //
103 0x00 , 0x00, 0x00,
104
105 //
106 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
107 //
108 0x00 , 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xa0,
109
110 //
111 //Bus , Dev, Func, LPC device
112 //
113 0x00 , 0x1F, 0x00,
114
115 //
116 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
117 //
118 0x00 , 0x08, 0x00, 0x07, 0x00, 0x00, 0x90, 0x00,
119
120 //
121 //Bus , Dev, Func, PCIE device
122 //
123 0x00 , 0x1C, 0x00,
124
125 //
126 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
127 //
128 0xC0 , 0x83, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
129
130 //
131 //Bus , Dev, Func, PCIE device
132 //
133 0x00 , 0x1C, 0x00,
134
135 //
136 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
137 //
138 0x03 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139
140 //
141 //Bus , Dev, Func, SATA device
142 //
143 0x00 , 0x13, 0x00,
144
145 //
146 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
147 //
148 0xf4 , 0xab, 0x27, 0x10, 0xf1, 0x1d, 0x00, 0x40,
149
150 //
151 //Bus , Dev, Func, EHCI device
152 //
153 0x00 , 0x1D, 0x00,
154
155 //
156 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
157 //
158 0x10 , 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
159
160 //
161 //Bus , Dev, Func, SMBUS device
162 //
163 0x00 , 0x1f, 0x03,
164
165 //
166 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
167 //
168 0x10 , 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169
170 //
171 //Bus , Dev, Func, SMBUS device
172 //
173 0x00 , 0x1f, 0x03,
174
175 //
176 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
177 //
178 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179
180 //
181 //Bus , Dev, Func, VGA bus1
182 //
183 0x01 , 0x00, 0x00,
184
185 //
186 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
187 //
188 0x58 , 0x81, 0x18, 0x01, 0xb0, 0x00, 0x00, 0x00,
189
190 //
191 //Bus , Dev, Func, VGA bus1
192 //
193 0x01 , 0x00, 0x00,
194
195 //
196 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
197 //
198 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199
200 //
201 //Bus , Dev, Func, VGA bus1 function 1
202 //
203 0x01 , 0x00, 0x01,
204
205 //
206 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
207 //
208 0x51 , 0x80, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
209
210 //
211 //Bus , Dev, Func, VGA bus1 function 1
212 //
213 0x01 , 0x00, 0x01,
214
215 //
216 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
217 //
218 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219
220 //
221 //Bus , Dev, Func, IGD bus0 function 0
222 //
223 0x00 , 0x02, 0x00,
224
225 //
226 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
227 //
228 0x42 , 0x81, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
229
230 //
231 //Bus , Dev, Func, USB bus0 function 0
232 //
233 0x00 , 0x16, 0x00,
234
235 //
236 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
237 //
238 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239
240 //
241 //Bus , Dev, Func, HD Audio bus0 function 0
242 //
243 0x00 , 0x1B, 0x00,
244
245 //
246 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
247 //
248 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
249
250 //
251 //0xFF indicates the end of the table
252 //
253 0xFF
254 };
255
256 //
257 // These registers have to set in byte order
258 //
259 UINT8 ExtReg[] = { 0x9E, 0x9D }; // SMRAM settings
260
261
262
263 //
264 // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
265 // and vital to S3 resume. That's why we put save code here
266 //
267 PciAddress.Bus = 0;
268 PciAddress.Device = 0;
269 PciAddress.Function = 0;
270 PciAddress.ExtendedRegister = 0;
271
272 for (Index = 0; Index < 2; Index++) {
273 //
274 // Read SRAM setting from Pci(0, 0, 0)
275 //
276 PciAddress.Register = ExtReg[Index];
277 Data8 = MmioRead8 (
278 MmPciAddress (0,
279 PciAddress.Bus,
280 PciAddress.Device,
281 PciAddress.Function,
282 PciAddress.Register
283 )
284 );
285
286 //
287 // Save latest settings to runtime script table
288 //
289 S3BootScriptSavePciCfgWrite(
290 S3BootScriptWidthUint8,
291 *(UINT64*)&PciAddress,
292 1,
293 &Data8
294 );
295 }
296
297
298 //
299 // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
300 // and vital to S3 resume. That's why we put save code here
301 //
302 Index = 0;
303 while (RegTable[Index] != 0xFF) {
304
305 PciAddress.Bus = RegTable[Index++];
306 PciAddress.Device = RegTable[Index++];
307 PciAddress.Function = RegTable[Index++];
308 PciAddress.Register = 0;
309 PciAddress.ExtendedRegister = 0;
310
311 Data16 = MmioRead16 (
312 MmPciAddress (0,
313 PciAddress.Bus,
314 PciAddress.Device,
315 PciAddress.Function,
316 PciAddress.Register
317 )
318 );
319
320 if (Data16 == 0xFFFF) {
321 Index+=8;
322 continue;
323 }
324
325 for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) {
326
327 if (Mask == 0x00) {
328 Mask = 0x01;
329 }
330
331 if (RegTable[Index + Offset/32] & Mask ) {
332
333 PciAddress.Register = (UINT8)Offset;
334 Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
335
336 //
337 // Save latest settings to runtime script table
338 //
339 S3BootScriptSavePciCfgWrite (
340 S3BootScriptWidthUint32,
341 *(UINT64*)&PciAddress,
342 1,
343 &Data32
344 );
345 }
346 }
347
348 Index += 8;
349
350 }
351
352
353 //
354 // Save I/O ports to S3 script table
355 //
356
357 //
358 // Selftest KBC
359 //
360 Data8 = 0xAA;
361 S3BootScriptSaveIoWrite (
362 S3BootScriptWidthUint8,
363 0x64,
364 (UINTN)1,
365 &Data8
366 );
367
368 Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
369
370 S3BootScriptSaveIoWrite (
371 S3BootScriptWidthUint32,
372 (mAcpiBaseAddr + R_PCH_SMI_EN),
373 1,
374 &Data32
375 );
376
377 //
378 // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
379 //
380 Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT);
381
382 S3BootScriptSaveIoWrite (
383 S3BootScriptWidthUint16,
384 mAcpiBaseAddr + R_PCH_TCO_CNT,
385 1,
386 &Data16
387 );
388
389
390 return EFI_SUCCESS;
391 }
392