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