blob: 6d12752b265688fb5aa33feb0fc32af6159ece97 [file] [log] [blame]
Frank Vibrans2b4c8312011-02-14 18:30:54 +00001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * ACPI S3 Support routines
6 *
7 * Contains routines needed for supporting resume from the ACPI S3 sleep state.
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: Interface
12 * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
13 *
14 */
15/*
16 *****************************************************************************
17 *
18 * Copyright (c) 2011, Advanced Micro Devices, Inc.
19 * All rights reserved.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100020 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000021 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100028 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
Frank Vibrans2b4c8312011-02-14 18:30:54 +000030 * from this software without specific prior written permission.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100031 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000032 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100042 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000043 * ***************************************************************************
44 *
45 */
46
47
48/*----------------------------------------------------------------------------------------
49 * M O D U L E S U S E D
50 *----------------------------------------------------------------------------------------
51 */
52#include "AGESA.h"
53#include "amdlib.h"
54#include "Ids.h"
55#include "mm.h"
56#include "mn.h"
57#include "S3.h"
58#include "mfs3.h"
59#include "GeneralServices.h"
60#include "cpuServices.h"
61#include "Filecode.h"
62CODE_GROUP (G1_PEICC)
63RDATA_GROUP (G1_PEICC)
64
65#define FILECODE PROC_CPU_S3_FILECODE
66/*----------------------------------------------------------------------------------------
67 * D E F I N I T I O N S A N D M A C R O S
68 *----------------------------------------------------------------------------------------
69 */
70
71
72/*----------------------------------------------------------------------------------------
73 * T Y P E D E F S A N D S T R U C T U R E S
74 *----------------------------------------------------------------------------------------
75 */
76
77
78/*----------------------------------------------------------------------------------------
79 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
80 *----------------------------------------------------------------------------------------
81 */
82VOID
83SaveDeviceContext (
84 IN DEVICE_BLOCK_HEADER *DeviceList,
85 IN CALL_POINTS CallPoint,
86 OUT UINT32 *ActualBufferSize,
87 IN AMD_CONFIG_PARAMS *StdHeader
88 );
89
90VOID
91SavePciDevice (
92 IN AMD_CONFIG_PARAMS *StdHeader,
93 IN PCI_DEVICE_DESCRIPTOR *Device,
94 IN CALL_POINTS CallPoint,
95 IN OUT VOID **OrMask
96 );
97
98VOID
99SaveConditionalPciDevice (
100 IN AMD_CONFIG_PARAMS *StdHeader,
101 IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
102 IN CALL_POINTS CallPoint,
103 IN OUT VOID **OrMask
104 );
105
106VOID
107SaveMsrDevice (
108 IN AMD_CONFIG_PARAMS *StdHeader,
109 IN MSR_DEVICE_DESCRIPTOR *Device,
110 IN CALL_POINTS CallPoint,
111 IN OUT UINT64 **OrMask
112 );
113
114VOID
115SaveConditionalMsrDevice (
116 IN AMD_CONFIG_PARAMS *StdHeader,
117 IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device,
118 IN CALL_POINTS CallPoint,
119 IN OUT UINT64 **OrMask
120 );
121
122VOID
123RestorePciDevice (
124 IN AMD_CONFIG_PARAMS *StdHeader,
125 IN PCI_DEVICE_DESCRIPTOR *Device,
126 IN CALL_POINTS CallPoint,
127 IN OUT VOID **OrMask
128 );
129
130VOID
131RestoreConditionalPciDevice (
132 IN AMD_CONFIG_PARAMS *StdHeader,
133 IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
134 IN CALL_POINTS CallPoint,
135 IN OUT VOID **OrMask
136 );
137
138VOID
139RestoreMsrDevice (
140 IN AMD_CONFIG_PARAMS *StdHeader,
141 IN MSR_DEVICE_DESCRIPTOR *Device,
142 IN CALL_POINTS CallPoint,
143 IN OUT UINT64 **OrMask
144 );
145
146VOID
147RestoreConditionalMsrDevice (
148 IN AMD_CONFIG_PARAMS *StdHeader,
149 IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device,
150 IN CALL_POINTS CallPoint,
151 IN OUT UINT64 **OrMask
152 );
153
154/*----------------------------------------------------------------------------------------
155 * E X P O R T E D F U N C T I O N S
156 *----------------------------------------------------------------------------------------
157 */
158
159/*---------------------------------------------------------------------------------------*/
160/**
161 * Saves all devices in the given device list.
162 *
163 * This traverses the entire device list twice. In the first pass, we save
164 * all devices identified as Pre ESR. In the second pass, we save devices
165 * marked as post ESR.
166 *
167 * @param[in] DeviceList Beginning of the device list to save.
168 * @param[in] Storage Beginning of the context buffer.
169 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
170 * AMD_S3LATE_RESTORE.
171 * @param[out] ActualBufferSize Actual size used in saving the device list.
172 * @param[in] StdHeader AMD standard header config param.
173 *
174 */
175VOID
176SaveDeviceListContext (
177 IN DEVICE_BLOCK_HEADER *DeviceList,
178 IN VOID *Storage,
179 IN CALL_POINTS CallPoint,
180 OUT UINT32 *ActualBufferSize,
181 IN AMD_CONFIG_PARAMS *StdHeader
182 )
183{
184 // Copy device list over
185 LibAmdMemCopy (Storage,
186 DeviceList,
187 (UINTN) DeviceList->RelativeOrMaskOffset,
188 StdHeader);
189 SaveDeviceContext (Storage, CallPoint, ActualBufferSize, StdHeader);
190}
191
192/*---------------------------------------------------------------------------------------*/
193/**
194 * Saves all devices in the given device list.
195 *
196 * This traverses the entire device list twice. In the first pass, we save
197 * all devices identified as Pre ESR. In the second pass, we save devices
198 * marked as post ESR.
199 *
200 * @param[in,out] DeviceList Beginning of the device list to save.
201 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
202 * AMD_S3LATE_RESTORE.
203 * @param[out] ActualBufferSize Actual size used in saving the device list.
204 * @param[in] StdHeader AMD standard header config param.
205 *
206 */
207VOID
208SaveDeviceContext (
209 IN DEVICE_BLOCK_HEADER *DeviceList,
210 IN CALL_POINTS CallPoint,
211 OUT UINT32 *ActualBufferSize,
212 IN AMD_CONFIG_PARAMS *StdHeader
213 )
214{
215 DEVICE_DESCRIPTORS Device;
216 UINT16 i;
efdesign9884cbce22011-08-04 12:09:17 -0600217 VOID *StartAddress;
218 VOID *EndAddress;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000219 VOID *OrMask;
220
efdesign9884cbce22011-08-04 12:09:17 -0600221 StartAddress = DeviceList;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000222 Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1];
223 OrMask = (UINT8 *) DeviceList + DeviceList->RelativeOrMaskOffset;
224
225 // Process Pre ESR List
226 for (i = 0; i < DeviceList->NumDevices; i++) {
227 switch (Device.CommonDeviceHeader->Type) {
228 case DEV_TYPE_PCI_PRE_ESR:
229 SavePciDevice (StdHeader, Device.PciDevice, CallPoint, &OrMask);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600230 // fall through - advance the pointer after saving context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000231 case DEV_TYPE_PCI:
232 Device.PciDevice++;
233 break;
234 case DEV_TYPE_CPCI_PRE_ESR:
235 SaveConditionalPciDevice (StdHeader, Device.CPciDevice, CallPoint, &OrMask);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600236 // fall through - advance the pointer after saving context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000237 case DEV_TYPE_CPCI:
238 Device.CPciDevice++;
239 break;
240 case DEV_TYPE_MSR_PRE_ESR:
241 SaveMsrDevice (StdHeader, Device.MsrDevice, CallPoint, (UINT64 **) &OrMask);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600242 // fall through - advance the pointer after saving context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000243 case DEV_TYPE_MSR:
244 Device.MsrDevice++;
245 break;
246 case DEV_TYPE_CMSR_PRE_ESR:
247 SaveConditionalMsrDevice (StdHeader, Device.CMsrDevice, CallPoint, (UINT64 **) &OrMask);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600248 // fall through - advance the pointer after saving context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000249 case DEV_TYPE_CMSR:
250 Device.CMsrDevice++;
251 break;
252 }
253 }
254
255 Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1];
256 // Process Post ESR List
257 for (i = 0; i < DeviceList->NumDevices; i++) {
258 switch (Device.CommonDeviceHeader->Type) {
259 case DEV_TYPE_PCI:
260 SavePciDevice (StdHeader, Device.PciDevice, CallPoint, &OrMask);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600261 // fall through - advance the pointer after saving context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000262 case DEV_TYPE_PCI_PRE_ESR:
263 Device.PciDevice++;
264 break;
265 case DEV_TYPE_CPCI:
266 SaveConditionalPciDevice (StdHeader, Device.CPciDevice, CallPoint, &OrMask);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600267 // fall through - advance the pointer after saving context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000268 case DEV_TYPE_CPCI_PRE_ESR:
269 Device.CPciDevice++;
270 break;
271 case DEV_TYPE_MSR:
272 SaveMsrDevice (StdHeader, Device.MsrDevice, CallPoint, (UINT64 **) &OrMask);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600273 // fall through - advance the pointer after saving context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000274 case DEV_TYPE_MSR_PRE_ESR:
275 Device.MsrDevice++;
276 break;
277 case DEV_TYPE_CMSR:
278 SaveConditionalMsrDevice (StdHeader, Device.CMsrDevice, CallPoint, (UINT64 **) &OrMask);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600279 // fall through - advance the pointer after saving context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000280 case DEV_TYPE_CMSR_PRE_ESR:
281 Device.CMsrDevice++;
282 break;
283 }
284 }
efdesign9884cbce22011-08-04 12:09:17 -0600285 EndAddress = (VOID *) OrMask;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000286 *ActualBufferSize = (UINT32) (EndAddress - StartAddress);
287}
288
289/*---------------------------------------------------------------------------------------*/
290/**
291 * Saves the context of a PCI device.
292 *
293 * This traverses the provided register list saving PCI registers.
294 *
295 * @param[in] StdHeader AMD standard header config param.
296 * @param[in] Device PCI device to restore.
297 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
298 * AMD_S3LATE_RESTORE.
299 * @param[in,out] OrMask Current buffer pointer of raw register values.
300 *
301 */
302VOID
303SavePciDevice (
304 IN AMD_CONFIG_PARAMS *StdHeader,
305 IN PCI_DEVICE_DESCRIPTOR *Device,
306 IN CALL_POINTS CallPoint,
307 IN OUT VOID **OrMask
308 )
309{
310 UINT8 RegSizeInBytes;
311 UINT8 SpecialCaseIndex;
312 UINT8 *IntermediatePtr;
313 UINT16 i;
314 UINT32 Socket;
315 UINT32 Module;
316 UINT32 AndMask;
317 ACCESS_WIDTH AccessWidth;
318 AGESA_STATUS IgnoredSts;
319 PCI_ADDR PciAddress;
320 PCI_REGISTER_BLOCK_HEADER *RegisterHdr;
321
322 GetSocketModuleOfNode ((UINT32) Device->Node,
323 &Socket,
324 &Module,
325 StdHeader);
326 GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);
327
328 if (CallPoint == INIT_RESUME) {
329 MemFS3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
330 } else {
331 S3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
332 }
333
334 for (i = 0; i < RegisterHdr->NumRegisters; i++) {
335 PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
336 PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
337 RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
338 switch (RegSizeInBytes) {
339 case 1:
340 AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
341 AccessWidth = AccessS3SaveWidth8;
342 break;
343 case 2:
344 AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
345 AccessWidth = AccessS3SaveWidth16;
346 break;
347 case 3:
348 // In this case, we don't need to save a register. We just need to call a special
349 // function to do certain things in the save and resume sequence.
350 // This should not be used in a non-special case.
351 AndMask = 0;
352 RegSizeInBytes = 0;
353 AccessWidth = 0;
354 break;
355 default:
356 AndMask = RegisterHdr->RegisterList[i].AndMask;
357 RegSizeInBytes = 4;
358 AccessWidth = AccessS3SaveWidth32;
359 break;
360 }
361 if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
362 ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0));
363 LibAmdPciRead (AccessWidth, PciAddress, *OrMask, StdHeader);
364 } else {
365 SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
366 RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, PciAddress, *OrMask, StdHeader);
367 }
368 if (AndMask != 0) {
369 // If AndMask is 0, then it is a not-care. Don't need to apply it to the OrMask
370 **((UINT32 **) OrMask) &= AndMask;
371 }
372 IntermediatePtr = (UINT8 *) *OrMask;
373 *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes;
374 }
375}
376
377/*---------------------------------------------------------------------------------------*/
378/**
379 * Saves the context of a 'conditional' PCI device.
380 *
381 * This traverses the provided register list saving PCI registers when appropriate.
382 *
383 * @param[in] StdHeader AMD standard header config param.
384 * @param[in] Device 'conditional' PCI device to restore.
385 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
386 * AMD_S3LATE_RESTORE.
387 * @param[in,out] OrMask Current buffer pointer of raw register values.
388 *
389 */
390VOID
391SaveConditionalPciDevice (
392 IN AMD_CONFIG_PARAMS *StdHeader,
393 IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
394 IN CALL_POINTS CallPoint,
395 IN OUT VOID **OrMask
396 )
397{
398 UINT8 RegSizeInBytes;
399 UINT8 SpecialCaseIndex;
400 UINT8 *IntermediatePtr;
401 UINT16 i;
402 UINT32 Socket;
403 UINT32 Module;
404 UINT32 AndMask;
405 ACCESS_WIDTH AccessWidth;
406 AGESA_STATUS IgnoredSts;
407 PCI_ADDR PciAddress;
408 CPCI_REGISTER_BLOCK_HEADER *RegisterHdr;
409
410 GetSocketModuleOfNode ((UINT32) Device->Node,
411 &Socket,
412 &Module,
413 StdHeader);
414 GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);
415
416 if (CallPoint == INIT_RESUME) {
417 MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
418 } else {
419 S3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
420 }
421
422 for (i = 0; i < RegisterHdr->NumRegisters; i++) {
423 if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) &&
424 ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) {
425 PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
426 PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
427 RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
428 switch (RegSizeInBytes) {
429 case 1:
430 AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
431 AccessWidth = AccessS3SaveWidth8;
432 break;
433 case 2:
434 AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
435 AccessWidth = AccessS3SaveWidth16;
436 break;
437 case 3:
438 // In this case, we don't need to save a register. We just need to call a special
439 // function to do certain things in the save and resume sequence.
440 // This should not be used in a non-special case.
441 AndMask = 0;
442 RegSizeInBytes = 0;
443 AccessWidth = 0;
444 break;
445 default:
446 AndMask = RegisterHdr->RegisterList[i].AndMask;
447 RegSizeInBytes = 4;
448 AccessWidth = AccessS3SaveWidth32;
449 break;
450 }
451 if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
452 ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0));
453 LibAmdPciRead (AccessWidth, PciAddress, *OrMask, StdHeader);
454 } else {
455 SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
456 RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, PciAddress, *OrMask, StdHeader);
457 }
458 if (AndMask != 0) {
459 // If AndMask is 0, then it is a not-care. Don't need to apply it to the OrMask
460 **((UINT32 **) OrMask) &= AndMask;
461 }
462 IntermediatePtr = (UINT8 *) *OrMask;
463 *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes;
464 }
465 }
466}
467
468/*---------------------------------------------------------------------------------------*/
469/**
470 * Saves the context of an MSR device.
471 *
472 * This traverses the provided register list saving MSRs.
473 *
474 * @param[in] StdHeader AMD standard header config param.
475 * @param[in] Device MSR device to restore.
476 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
477 * AMD_S3LATE_RESTORE.
478 * @param[in,out] OrMask Current buffer pointer of raw register values.
479 *
480 */
481VOID
482SaveMsrDevice (
483 IN AMD_CONFIG_PARAMS *StdHeader,
484 IN MSR_DEVICE_DESCRIPTOR *Device,
485 IN CALL_POINTS CallPoint,
486 IN OUT UINT64 **OrMask
487 )
488{
489 UINT8 SpecialCaseIndex;
490 UINT16 i;
491 MSR_REGISTER_BLOCK_HEADER *RegisterHdr;
492
493 if (CallPoint == INIT_RESUME) {
494 MemFS3GetMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader);
495 } else {
496 S3GetMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader);
497 }
498
499 for (i = 0; i < RegisterHdr->NumRegisters; i++) {
500 if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
501 LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, *OrMask, StdHeader);
502 } else {
503 SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
504 RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address, *OrMask, StdHeader);
505 }
506 **OrMask &= RegisterHdr->RegisterList[i].AndMask;
507 (*OrMask)++;
508 }
509}
510
511/*---------------------------------------------------------------------------------------*/
512/**
513 * Saves the context of a 'conditional' MSR device.
514 *
515 * This traverses the provided register list saving MSRs when appropriate.
516 *
517 * @param[in] StdHeader AMD standard header config param.
518 * @param[in] Device 'conditional' MSR device to restore.
519 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
520 * AMD_S3LATE_RESTORE.
521 * @param[in,out] OrMask Current buffer pointer of raw register values.
522 *
523 */
524VOID
525SaveConditionalMsrDevice (
526 IN AMD_CONFIG_PARAMS *StdHeader,
527 IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device,
528 IN CALL_POINTS CallPoint,
529 IN OUT UINT64 **OrMask
530 )
531{
532 UINT8 SpecialCaseIndex;
533 UINT16 i;
534 CMSR_REGISTER_BLOCK_HEADER *RegisterHdr;
535
536 if (CallPoint == INIT_RESUME) {
537 MemFS3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader);
538 } else {
539 S3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader);
540 }
541
542 for (i = 0; i < RegisterHdr->NumRegisters; i++) {
543 if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) &&
544 ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) {
545 if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
546 LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, (UINT64 *) *OrMask, StdHeader);
547 } else {
548 SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
549 RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address, (UINT64 *) *OrMask, StdHeader);
550 }
551 **OrMask &= RegisterHdr->RegisterList[i].AndMask;
552 (*OrMask)++;
553 }
554 }
555}
556
557/*---------------------------------------------------------------------------------------*/
558/**
559 * Determines the maximum amount of space required to store all raw register
560 * values for the given device list.
561 *
562 * This traverses the entire device list, and calculates the worst case size
563 * of each device in the device list.
564 *
565 * @param[in] DeviceList Beginning of the device list.
566 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
567 * AMD_S3LATE_RESTORE.
568 * @param[in] StdHeader AMD standard header config param.
569 *
570 * @retval Size in bytes required for storing all registers.
571 */
572UINT32
573GetWorstCaseContextSize (
574 IN DEVICE_BLOCK_HEADER *DeviceList,
575 IN CALL_POINTS CallPoint,
576 IN AMD_CONFIG_PARAMS *StdHeader
577 )
578{
579 UINT32 WorstCaseSize;
580 DEVICE_DESCRIPTORS Device;
581 UINT16 i;
582 REGISTER_BLOCK_HEADERS RegisterHdr;
583
584 WorstCaseSize = DeviceList->RelativeOrMaskOffset;
585 Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1];
586
587 // Process Device List
588 for (i = 0; i < DeviceList->NumDevices; i++) {
589 switch (Device.CommonDeviceHeader->Type) {
590 case DEV_TYPE_PCI_PRE_ESR:
591 // PRE_ESR and post ESR take the same amount of space
592 case DEV_TYPE_PCI:
593 if (CallPoint == INIT_RESUME) {
594 MemFS3GetPciDeviceRegisterList (Device.PciDevice, &RegisterHdr.PciRegisters, StdHeader);
595 } else {
596 S3GetPciDeviceRegisterList (Device.PciDevice, &RegisterHdr.PciRegisters, StdHeader);
597 }
598 WorstCaseSize += (RegisterHdr.PciRegisters->NumRegisters * 4);
599 Device.PciDevice++;
600 break;
601 case DEV_TYPE_CPCI_PRE_ESR:
602 // PRE_ESR and post ESR take the same amount of space
603 case DEV_TYPE_CPCI:
604 if (CallPoint == INIT_RESUME) {
605 MemFS3GetCPciDeviceRegisterList (Device.CPciDevice, &RegisterHdr.CPciRegisters, StdHeader);
606 } else {
607 S3GetCPciDeviceRegisterList (Device.CPciDevice, &RegisterHdr.CPciRegisters, StdHeader);
608 }
609 WorstCaseSize += (RegisterHdr.CPciRegisters->NumRegisters * 4);
610 Device.CPciDevice++;
611 break;
612 case DEV_TYPE_MSR_PRE_ESR:
613 // PRE_ESR and post ESR take the same amount of space
614 case DEV_TYPE_MSR:
615 if (CallPoint == INIT_RESUME) {
616 MemFS3GetMsrDeviceRegisterList (Device.MsrDevice, &RegisterHdr.MsrRegisters, StdHeader);
617 } else {
618 S3GetMsrDeviceRegisterList (Device.MsrDevice, &RegisterHdr.MsrRegisters, StdHeader);
619 }
620 WorstCaseSize += (RegisterHdr.MsrRegisters->NumRegisters * 8);
621 Device.MsrDevice++;
622 break;
623 case DEV_TYPE_CMSR_PRE_ESR:
624 // PRE_ESR and post ESR take the same amount of space
625 case DEV_TYPE_CMSR:
626 if (CallPoint == INIT_RESUME) {
627 MemFS3GetCMsrDeviceRegisterList (Device.CMsrDevice, &RegisterHdr.CMsrRegisters, StdHeader);
628 } else {
629 S3GetCMsrDeviceRegisterList (Device.CMsrDevice, &RegisterHdr.CMsrRegisters, StdHeader);
630 }
631 WorstCaseSize += (RegisterHdr.CMsrRegisters->NumRegisters * 8);
632 Device.CMsrDevice++;
633 break;
634 default:
635 ASSERT (FALSE);
636 }
637 }
638 return (WorstCaseSize);
639}
640
641/*---------------------------------------------------------------------------------------*/
642/**
643 * Restores all devices marked as 'before exiting self-refresh.'
644 *
645 * This traverses the entire device list, restoring all devices identified
646 * as Pre ESR.
647 *
648 * @param[in,out] OrMaskPtr Current buffer pointer of raw register values.
649 * @param[in] Storage Beginning of the device list.
650 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
651 * AMD_S3LATE_RESTORE.
652 * @param[in] StdHeader AMD standard header config param.
653 *
654 */
655VOID
656RestorePreESRContext (
657 OUT VOID **OrMaskPtr,
658 IN VOID *Storage,
659 IN CALL_POINTS CallPoint,
660 IN AMD_CONFIG_PARAMS *StdHeader
661 )
662{
663 DEVICE_DESCRIPTORS Device;
664 UINT16 i;
665 DEVICE_BLOCK_HEADER *DeviceList;
666
667 DeviceList = (DEVICE_BLOCK_HEADER *) Storage;
668 Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1];
669 *OrMaskPtr = (UINT8 *) DeviceList + DeviceList->RelativeOrMaskOffset;
670
671 // Process Pre ESR List
672 for (i = 0; i < DeviceList->NumDevices; i++) {
673 switch (Device.CommonDeviceHeader->Type) {
674 case DEV_TYPE_PCI_PRE_ESR:
675 RestorePciDevice (StdHeader, Device.PciDevice, CallPoint, OrMaskPtr);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600676 // fall through - advance the pointer after restoring context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000677 case DEV_TYPE_PCI:
678 Device.PciDevice++;
679 break;
680 case DEV_TYPE_CPCI_PRE_ESR:
681 RestoreConditionalPciDevice (StdHeader, Device.CPciDevice, CallPoint, OrMaskPtr);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600682 // fall through - advance the pointer after restoring context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000683 case DEV_TYPE_CPCI:
684 Device.CPciDevice++;
685 break;
686 case DEV_TYPE_MSR_PRE_ESR:
687 RestoreMsrDevice (StdHeader, Device.MsrDevice, CallPoint, (UINT64 **) OrMaskPtr);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600688 // fall through - advance the pointer after restoring context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000689 case DEV_TYPE_MSR:
690 Device.MsrDevice++;
691 break;
692 case DEV_TYPE_CMSR_PRE_ESR:
693 RestoreConditionalMsrDevice (StdHeader, Device.CMsrDevice, CallPoint, (UINT64 **) OrMaskPtr);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600694 // fall through - advance the pointer after restoring context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000695 case DEV_TYPE_CMSR:
696 Device.CMsrDevice++;
697 break;
698 }
699 }
700}
701
702/*---------------------------------------------------------------------------------------*/
703/**
704 * Restores all devices marked as 'after exiting self-refresh.'
705 *
706 * This traverses the entire device list, restoring all devices identified
707 * as Post ESR.
708 *
709 * @param[in] OrMaskPtr Current buffer pointer of raw register values.
710 * @param[in] Storage Beginning of the device list.
711 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
712 * AMD_S3LATE_RESTORE.
713 * @param[in] StdHeader AMD standard header config param.
714 *
715 */
716VOID
717RestorePostESRContext (
718 IN VOID *OrMaskPtr,
719 IN VOID *Storage,
720 IN CALL_POINTS CallPoint,
721 IN AMD_CONFIG_PARAMS *StdHeader
722 )
723{
724 DEVICE_DESCRIPTORS Device;
725 UINT16 i;
726 DEVICE_BLOCK_HEADER *DeviceList;
727
728 DeviceList = (DEVICE_BLOCK_HEADER *) Storage;
729 Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1];
730
731 // Process Pre ESR List
732 for (i = 0; i < DeviceList->NumDevices; i++) {
733 switch (Device.CommonDeviceHeader->Type) {
734 case DEV_TYPE_PCI:
735 RestorePciDevice (StdHeader, Device.PciDevice, CallPoint, &OrMaskPtr);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600736 // fall through - advance the pointer after restoring context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000737 case DEV_TYPE_PCI_PRE_ESR:
738 Device.PciDevice++;
739 break;
740 case DEV_TYPE_CPCI:
741 RestoreConditionalPciDevice (StdHeader, Device.CPciDevice, CallPoint, &OrMaskPtr);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600742 // fall through - advance the pointer after restoring context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000743 case DEV_TYPE_CPCI_PRE_ESR:
744 Device.CPciDevice++;
745 break;
746 case DEV_TYPE_MSR:
747 RestoreMsrDevice (StdHeader, Device.MsrDevice, CallPoint, (UINT64 **) &OrMaskPtr);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600748 // fall through - advance the pointer after restoring context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000749 case DEV_TYPE_MSR_PRE_ESR:
750 Device.MsrDevice++;
751 break;
752 case DEV_TYPE_CMSR:
753 RestoreConditionalMsrDevice (StdHeader, Device.CMsrDevice, CallPoint, (UINT64 **) &OrMaskPtr);
Jacob Garber4c33a3a2019-07-12 10:34:06 -0600754 // fall through - advance the pointer after restoring context
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000755 case DEV_TYPE_CMSR_PRE_ESR:
756 Device.CMsrDevice++;
757 break;
758 }
759 }
760}
761
762/*---------------------------------------------------------------------------------------*/
763/**
764 * Restores the context of a PCI device.
765 *
766 * This traverses the provided register list restoring PCI registers.
767 *
768 * @param[in] StdHeader AMD standard header config param.
769 * @param[in] Device 'conditional' PCI device to restore.
770 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
771 * AMD_S3LATE_RESTORE.
772 * @param[in,out] OrMask Current buffer pointer of raw register values.
773 *
774 */
775VOID
776RestorePciDevice (
777 IN AMD_CONFIG_PARAMS *StdHeader,
778 IN PCI_DEVICE_DESCRIPTOR *Device,
779 IN CALL_POINTS CallPoint,
780 IN OUT VOID **OrMask
781 )
782{
783 UINT8 RegSizeInBytes;
784 UINT8 SpecialCaseIndex;
785 UINT8 *IntermediatePtr;
786 UINT16 i;
787 UINT32 Socket;
788 UINT32 Module;
789 UINT32 AndMask;
790 UINT32 RegValueRead;
791 UINT32 RegValueWrite;
792 ACCESS_WIDTH AccessWidth;
793 AGESA_STATUS IgnoredSts;
794 PCI_ADDR PciAddress;
795 PCI_REGISTER_BLOCK_HEADER *RegisterHdr;
796
797 GetSocketModuleOfNode ((UINT32) Device->Node,
798 &Socket,
799 &Module,
800 StdHeader);
801 GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);
802
803 if (CallPoint == INIT_RESUME) {
804 MemFS3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
805 } else {
806 S3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
807 }
808
809 for (i = 0; i < RegisterHdr->NumRegisters; i++) {
810 PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
811 PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
812 RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
813 switch (RegSizeInBytes) {
814 case 1:
815 AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
816 RegValueWrite = **(UINT8 **)OrMask;
817 AccessWidth = AccessS3SaveWidth8;
818 break;
819 case 2:
820 AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
821 RegValueWrite = **(UINT16 **)OrMask;
822 AccessWidth = AccessS3SaveWidth16;
823 break;
824 case 3:
825 // In this case, we don't need to restore a register. We just need to call a special
826 // function to do certain things in the save and resume sequence.
827 // This should not be used in a non-special case.
828 AndMask = 0;
829 RegValueWrite = 0;
830 RegSizeInBytes = 0;
831 AccessWidth = 0;
832 break;
833 default:
834 AndMask = RegisterHdr->RegisterList[i].AndMask;
835 RegSizeInBytes = 4;
836 RegValueWrite = **(UINT32 **)OrMask;
837 AccessWidth = AccessS3SaveWidth32;
838 break;
839 }
840 if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
841 ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0));
842 LibAmdPciRead (AccessWidth, PciAddress, &RegValueRead, StdHeader);
843 RegValueWrite |= RegValueRead & (~AndMask);
844 LibAmdPciWrite (AccessWidth, PciAddress, &RegValueWrite, StdHeader);
845 } else {
846 SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
847 if (AndMask != 0) {
848 RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth,
849 PciAddress,
850 &RegValueRead,
851 StdHeader);
852 RegValueWrite |= RegValueRead & (~AndMask);
853 }
854 RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth,
855 PciAddress,
856 &RegValueWrite,
857 StdHeader);
858 }
859 IntermediatePtr = (UINT8 *) *OrMask;
860 *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes;
861 }
862}
863
864/*---------------------------------------------------------------------------------------*/
865/**
866 * Restores the context of a 'conditional' PCI device.
867 *
868 * This traverses the provided register list restoring PCI registers when appropriate.
869 *
870 * @param[in] StdHeader AMD standard header config param.
871 * @param[in] Device 'conditional' PCI device to restore.
872 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
873 * AMD_S3LATE_RESTORE.
874 * @param[in,out] OrMask Current buffer pointer of raw register values.
875 *
876 */
877VOID
878RestoreConditionalPciDevice (
879 IN AMD_CONFIG_PARAMS *StdHeader,
880 IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
881 IN CALL_POINTS CallPoint,
882 IN OUT VOID **OrMask
883 )
884{
885 UINT8 RegSizeInBytes;
886 UINT8 SpecialCaseIndex;
887 UINT8 *IntermediatePtr;
888 UINT16 i;
889 UINT32 Socket;
890 UINT32 Module;
891 UINT32 RegValueRead;
892 UINT32 RegValueWrite;
893 UINT32 AndMask;
894 ACCESS_WIDTH AccessWidth;
895 AGESA_STATUS IgnoredSts;
896 PCI_ADDR PciAddress;
897 CPCI_REGISTER_BLOCK_HEADER *RegisterHdr;
898
899 GetSocketModuleOfNode ((UINT32) Device->Node,
900 &Socket,
901 &Module,
902 StdHeader);
903 GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);
904
905 if (CallPoint == INIT_RESUME) {
906 MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
907 } else {
908 S3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
909 }
910
911 for (i = 0; i < RegisterHdr->NumRegisters; i++) {
912 if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) &&
913 ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) {
914 PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
915 PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
916 RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
917 switch (RegSizeInBytes) {
918 case 1:
919 AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
920 RegValueWrite = **(UINT8 **)OrMask;
921 AccessWidth = AccessS3SaveWidth8;
922 break;
923 case 2:
924 AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
925 RegValueWrite = **(UINT16 **)OrMask;
926 AccessWidth = AccessS3SaveWidth16;
927 break;
928 case 3:
929 // In this case, we don't need to restore a register. We just need to call a special
930 // function to do certain things in the save and resume sequence.
931 // This should not be used in a non-special case.
932 AndMask = 0;
933 RegValueWrite = 0;
934 RegSizeInBytes = 0;
935 AccessWidth = 0;
936 break;
937 default:
938 AndMask = RegisterHdr->RegisterList[i].AndMask;
939 RegSizeInBytes = 4;
940 RegValueWrite = **(UINT32 **)OrMask;
941 AccessWidth = AccessS3SaveWidth32;
942 break;
943 }
944 if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
945 LibAmdPciRead (AccessWidth, PciAddress, &RegValueRead, StdHeader);
946 RegValueWrite |= RegValueRead & (~AndMask);
947 LibAmdPciWrite (AccessWidth, PciAddress, &RegValueWrite, StdHeader);
948 } else {
949 SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
950 if (AndMask != 0) {
951 RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth,
952 PciAddress,
953 &RegValueRead,
954 StdHeader);
955 RegValueWrite |= RegValueRead & (~AndMask);
956 }
957 RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth,
958 PciAddress,
959 &RegValueWrite,
960 StdHeader);
961 }
962 IntermediatePtr = (UINT8 *) *OrMask;
963 *OrMask = &IntermediatePtr[RegSizeInBytes];
964 }
965 }
966}
967
968/*---------------------------------------------------------------------------------------*/
969/**
970 * Restores the context of an MSR device.
971 *
972 * This traverses the provided register list restoring MSRs.
973 *
974 * @param[in] StdHeader AMD standard header config param.
975 * @param[in] Device MSR device to restore.
976 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
977 * AMD_S3LATE_RESTORE.
978 * @param[in,out] OrMask Current buffer pointer of raw register values.
979 *
980 */
981VOID
982RestoreMsrDevice (
983 IN AMD_CONFIG_PARAMS *StdHeader,
984 IN MSR_DEVICE_DESCRIPTOR *Device,
985 IN CALL_POINTS CallPoint,
986 IN OUT UINT64 **OrMask
987 )
988{
989 UINT8 SpecialCaseIndex;
990 UINT16 i;
991 UINT64 RegValueRead;
992 UINT64 RegValueWrite;
993 MSR_REGISTER_BLOCK_HEADER *RegisterHdr;
994
995 if (CallPoint == INIT_RESUME) {
996 MemFS3GetMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader);
997 } else {
998 S3GetMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader);
999 }
1000
1001 for (i = 0; i < RegisterHdr->NumRegisters; i++) {
1002 RegValueWrite = **OrMask;
1003 if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
1004 LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, &RegValueRead, StdHeader);
1005 RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask);
1006 LibAmdMsrWrite (RegisterHdr->RegisterList[i].Address, &RegValueWrite, StdHeader);
1007 } else {
1008 SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
1009 RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address,
1010 &RegValueRead,
1011 StdHeader);
1012 RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask);
1013 RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (RegisterHdr->RegisterList[i].Address,
1014 &RegValueWrite,
1015 StdHeader);
1016 }
1017 (*OrMask)++;
1018 }
1019}
1020
1021/*---------------------------------------------------------------------------------------*/
1022/**
1023 * Restores the context of a 'conditional' MSR device.
1024 *
1025 * This traverses the provided register list restoring MSRs when appropriate.
1026 *
1027 * @param[in] StdHeader AMD standard header config param.
1028 * @param[in] Device 'conditional' MSR device to restore.
1029 * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or
1030 * AMD_S3LATE_RESTORE.
1031 * @param[in,out] OrMask Current buffer pointer of raw register values.
1032 *
1033 */
1034VOID
1035RestoreConditionalMsrDevice (
1036 IN AMD_CONFIG_PARAMS *StdHeader,
1037 IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device,
1038 IN CALL_POINTS CallPoint,
1039 IN OUT UINT64 **OrMask
1040 )
1041{
1042 UINT8 SpecialCaseIndex;
1043 UINT16 i;
1044 UINT64 RegValueRead;
1045 UINT64 RegValueWrite;
1046 CMSR_REGISTER_BLOCK_HEADER *RegisterHdr;
1047
1048 if (CallPoint == INIT_RESUME) {
1049 MemFS3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader);
1050 } else {
1051 S3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader);
1052 }
1053
1054 for (i = 0; i < RegisterHdr->NumRegisters; i++) {
1055 if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) &&
1056 ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) {
1057 RegValueWrite = **OrMask;
1058 if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
1059 LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, &RegValueRead, StdHeader);
1060 RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask);
1061 LibAmdMsrWrite (RegisterHdr->RegisterList[i].Address, &RegValueWrite, StdHeader);
1062 } else {
1063 SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
1064 RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address,
1065 &RegValueRead,
1066 StdHeader);
1067 RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask);
1068 RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (RegisterHdr->RegisterList[i].Address,
1069 &RegValueWrite,
1070 StdHeader);
1071 }
1072 (*OrMask)++;
1073 }
1074 }
1075}
1076
1077/*---------------------------------------------------------------------------------------*/
1078/**
1079 * Unique device ID to PCI register list translator.
1080 *
1081 * This translates the given device header in storage to the appropriate list
1082 * of registers in the AGESA image.
1083 *
1084 * @param[out] NonMemoryRelatedDeviceList List of devices to save and restore
1085 * during S3LateRestore.
1086 * @param[in] StdHeader AMD standard header config param.
1087 *
1088 */
1089VOID
1090GetNonMemoryRelatedDeviceList (
1091 OUT DEVICE_BLOCK_HEADER **NonMemoryRelatedDeviceList,
1092 IN AMD_CONFIG_PARAMS *StdHeader
1093 )
1094{
1095 *NonMemoryRelatedDeviceList = NULL;
1096}
1097
1098/*---------------------------------------------------------------------------------------*/
1099/**
1100 * Unique device ID to PCI register list translator.
1101 *
1102 * This translates the given device header in storage to the appropriate list
1103 * of registers in the AGESA image.
1104 *
1105 * @param[in] Device Device header containing the unique ID.
1106 * @param[out] RegisterHdr Output PCI register list pointer.
1107 * @param[in] StdHeader AMD standard header config param.
1108 *
1109 * @retval AGESA_SUCCESS Always succeeds.
1110 */
1111AGESA_STATUS
1112S3GetPciDeviceRegisterList (
1113 IN PCI_DEVICE_DESCRIPTOR *Device,
1114 OUT PCI_REGISTER_BLOCK_HEADER **RegisterHdr,
1115 IN AMD_CONFIG_PARAMS *StdHeader
1116 )
1117{
1118 *RegisterHdr = NULL;
1119 return AGESA_SUCCESS;
1120}
1121
1122/*---------------------------------------------------------------------------------------*/
1123/**
1124 * Unique device ID to 'conditional' PCI register list translator.
1125 *
1126 * This translates the given device header in storage to the appropriate list
1127 * of registers in the AGESA image.
1128 *
1129 * @param[in] Device Device header containing the unique ID.
1130 * @param[out] RegisterHdr Output 'conditional' PCI register list pointer.
1131 * @param[in] StdHeader AMD standard header config param.
1132 *
1133 * @retval AGESA_SUCCESS Always succeeds.
1134 */
1135AGESA_STATUS
1136S3GetCPciDeviceRegisterList (
1137 IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
1138 OUT CPCI_REGISTER_BLOCK_HEADER **RegisterHdr,
1139 IN AMD_CONFIG_PARAMS *StdHeader
1140 )
1141{
1142 *RegisterHdr = NULL;
1143 return AGESA_SUCCESS;
1144}
1145
1146
1147/*---------------------------------------------------------------------------------------*/
1148/**
1149 * Unique device ID to MSR register list translator.
1150 *
1151 * This translates the given device header in storage to the appropriate list
1152 * of registers in the AGESA image.
1153 *
1154 * @param[in] Device Device header containing the unique ID.
1155 * @param[out] RegisterHdr Output MSR register list pointer.
1156 * @param[in] StdHeader AMD standard header config param.
1157 *
1158 * @retval AGESA_SUCCESS Always succeeds.
1159 */
1160AGESA_STATUS
1161S3GetMsrDeviceRegisterList (
1162 IN MSR_DEVICE_DESCRIPTOR *Device,
1163 OUT MSR_REGISTER_BLOCK_HEADER **RegisterHdr,
1164 IN AMD_CONFIG_PARAMS *StdHeader
1165 )
1166{
1167 *RegisterHdr = NULL;
1168 return AGESA_SUCCESS;
1169}
1170
1171/*---------------------------------------------------------------------------------------*/
1172/**
1173 * Unique device ID to 'conditional' MSR register list translator.
1174 *
1175 * This translates the given device header in storage to the appropriate list
1176 * of registers in the AGESA image.
1177 *
1178 * @param[in] Device Device header containing the unique ID.
1179 * @param[out] RegisterHdr Output 'conditional' MSR register list pointer.
1180 * @param[in] StdHeader AMD standard header config param.
1181 *
1182 * @retval AGESA_SUCCESS Always succeeds.
1183 */
1184AGESA_STATUS
1185S3GetCMsrDeviceRegisterList (
1186 IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device,
1187 OUT CMSR_REGISTER_BLOCK_HEADER **RegisterHdr,
1188 IN AMD_CONFIG_PARAMS *StdHeader
1189 )
1190{
1191 *RegisterHdr = NULL;
1192 return AGESA_SUCCESS;
1193}
1194
1195/*---------------------------------------------------------------------------------------*/
1196/**
1197 * Constructor for the AMD_S3_PARAMS structure.
1198 *
1199 * This routine initializes failsafe values for the AMD_S3_PARAMS structure
1200 * to be used by the AMD_INIT_RESUME, AMD_S3_SAVE, and AMD_S3LATE_RESTORE
1201 * entry points.
1202 *
1203 * @param[in,out] S3Params Required input parameter for the AMD_S3_SAVE,
1204 * AMD_INIT_RESUME, and AMD_S3_SAVE entry points.
1205 *
1206 */
1207VOID
1208AmdS3ParamsInitializer (
1209 OUT AMD_S3_PARAMS *S3Params
1210 )
1211{
1212 S3Params->Signature = 0x52545341;
1213 S3Params->Version = 0x0000;
1214 S3Params->VolatileStorage = NULL;
1215 S3Params->VolatileStorageSize = 0x00000000;
1216 S3Params->Flags = 0x00000000;
1217 S3Params->NvStorage = NULL;
1218 S3Params->NvStorageSize = 0x00000000;
1219}