1 /** @file
2   PCI configuration Library Services that do PCI configuration and also enable
3   the PCI operations to be replayed during an S3 resume. This library class
4   maps directly on top of the PciLib class.
5 
6   Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
7 
8   This program and the accompanying materials
9   are licensed and made available under the terms and conditions
10   of the BSD License which accompanies this distribution.  The
11   full text of the license may be found at
12   http://opensource.org/licenses/bsd-license.php
13 
14   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 
17 **/
18 
19 
20 #include <Base.h>
21 
22 #include <Library/DebugLib.h>
23 #include <Library/S3BootScriptLib.h>
24 #include <Library/PciLib.h>
25 #include <Library/S3PciLib.h>
26 
27 #define PCILIB_TO_COMMON_ADDRESS(Address) \
28         ((UINT64) ((((UINTN) ((Address>>20) & 0xff)) << 24) + (((UINTN) ((Address>>15) & 0x1f)) << 16) + (((UINTN) ((Address>>12) & 0x07)) << 8) + ((UINTN) (Address & 0xfff ))))
29 
30 /**
31   Saves a PCI configuration value to the boot script.
32 
33   This internal worker function saves a PCI configuration value in
34   the S3 script to be replayed on S3 resume.
35 
36   If the saving process fails, then ASSERT().
37 
38   @param  Width   The width of PCI configuration.
39   @param  Address Address that encodes the PCI Bus, Device, Function and
40                   Register.
41   @param  Buffer  The buffer containing value.
42 
43 **/
44 VOID
InternalSavePciWriteValueToBootScript(IN S3_BOOT_SCRIPT_LIB_WIDTH Width,IN UINTN Address,IN VOID * Buffer)45 InternalSavePciWriteValueToBootScript (
46   IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,
47   IN UINTN                  Address,
48   IN VOID                   *Buffer
49   )
50 {
51   RETURN_STATUS                Status;
52 
53   Status = S3BootScriptSavePciCfgWrite (
54              Width,
55              PCILIB_TO_COMMON_ADDRESS(Address),
56              1,
57              Buffer
58              );
59   ASSERT (Status == RETURN_SUCCESS);
60 }
61 
62 /**
63   Saves an 8-bit PCI configuration value to the boot script.
64 
65   This internal worker function saves an 8-bit PCI configuration value in
66   the S3 script to be replayed on S3 resume.
67 
68   If the saving process fails, then ASSERT().
69 
70   @param  Address Address that encodes the PCI Bus, Device, Function and
71                   Register.
72   @param  Value   The value saved to boot script.
73 
74   @return Value.
75 
76 **/
77 UINT8
InternalSavePciWrite8ValueToBootScript(IN UINTN Address,IN UINT8 Value)78 InternalSavePciWrite8ValueToBootScript (
79   IN UINTN              Address,
80   IN UINT8              Value
81   )
82 {
83   InternalSavePciWriteValueToBootScript (S3BootScriptWidthUint8, Address, &Value);
84 
85   return Value;
86 }
87 
88 /**
89   Reads an 8-bit PCI configuration register and saves the value in the S3
90   script to be replayed on S3 resume.
91 
92   Reads and returns the 8-bit PCI configuration register specified by Address.
93   This function must guarantee that all PCI read and write operations are
94   serialized.
95 
96   If Address > 0x0FFFFFFF, then ASSERT().
97 
98   @param  Address Address that encodes the PCI Bus, Device, Function and
99                   Register.
100 
101   @return The read value from the PCI configuration register.
102 
103 **/
104 UINT8
105 EFIAPI
S3PciRead8(IN UINTN Address)106 S3PciRead8 (
107   IN UINTN                     Address
108   )
109 {
110   return InternalSavePciWrite8ValueToBootScript (Address, PciRead8 (Address));
111 }
112 
113 /**
114   Writes an 8-bit PCI configuration register and saves the value in the S3
115   script to be replayed on S3 resume.
116 
117   Writes the 8-bit PCI configuration register specified by Address with the
118   value specified by Value. Value is returned. This function must guarantee
119   that all PCI read and write operations are serialized.
120 
121   If Address > 0x0FFFFFFF, then ASSERT().
122 
123   @param  Address Address that encodes the PCI Bus, Device, Function and
124                   Register.
125   @param  Value   The value to write.
126 
127   @return The value written to the PCI configuration register.
128 
129 **/
130 UINT8
131 EFIAPI
S3PciWrite8(IN UINTN Address,IN UINT8 Value)132 S3PciWrite8 (
133   IN UINTN                     Address,
134   IN UINT8                     Value
135   )
136 {
137   return InternalSavePciWrite8ValueToBootScript (Address, PciWrite8 (Address, Value));
138 }
139 
140 /**
141   Performs a bitwise OR of an 8-bit PCI configuration register with
142   an 8-bit value and saves the value in the S3 script to be replayed on S3 resume.
143 
144   Reads the 8-bit PCI configuration register specified by Address, performs a
145   bitwise OR between the read result and the value specified by
146   OrData, and writes the result to the 8-bit PCI configuration register
147   specified by Address. The value written to the PCI configuration register is
148   returned. This function must guarantee that all PCI read and write operations
149   are serialized.
150 
151   If Address > 0x0FFFFFFF, then ASSERT().
152 
153   @param  Address Address that encodes the PCI Bus, Device, Function and
154                   Register.
155   @param  OrData  The value to OR with the PCI configuration register.
156 
157   @return The value written back to the PCI configuration register.
158 
159 **/
160 UINT8
161 EFIAPI
S3PciOr8(IN UINTN Address,IN UINT8 OrData)162 S3PciOr8 (
163   IN UINTN                     Address,
164   IN UINT8                     OrData
165   )
166 {
167   return InternalSavePciWrite8ValueToBootScript (Address, PciOr8 (Address, OrData));
168 }
169 
170 /**
171   Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
172   value and saves the value in the S3 script to be replayed on S3 resume.
173 
174   Reads the 8-bit PCI configuration register specified by Address, performs a
175   bitwise AND between the read result and the value specified by AndData, and
176   writes the result to the 8-bit PCI configuration register specified by
177   Address. The value written to the PCI configuration register is returned.
178   This function must guarantee that all PCI read and write operations are
179   serialized.
180 
181   If Address > 0x0FFFFFFF, then ASSERT().
182 
183   @param  Address Address that encodes the PCI Bus, Device, Function and
184                   Register.
185   @param  AndData The value to AND with the PCI configuration register.
186 
187   @return The value written back to the PCI configuration register.
188 
189 **/
190 UINT8
191 EFIAPI
S3PciAnd8(IN UINTN Address,IN UINT8 AndData)192 S3PciAnd8 (
193   IN UINTN                     Address,
194   IN UINT8                     AndData
195   )
196 {
197   return InternalSavePciWrite8ValueToBootScript (Address, PciAnd8 (Address, AndData));
198 }
199 
200 /**
201   Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
202   value, followed a  bitwise OR with another 8-bit value and saves
203   the value in the S3 script to be replayed on S3 resume.
204 
205   Reads the 8-bit PCI configuration register specified by Address, performs a
206   bitwise AND between the read result and the value specified by AndData,
207   performs a bitwise OR between the result of the AND operation and
208   the value specified by OrData, and writes the result to the 8-bit PCI
209   configuration register specified by Address. The value written to the PCI
210   configuration register is returned. This function must guarantee that all PCI
211   read and write operations are serialized.
212 
213   If Address > 0x0FFFFFFF, then ASSERT().
214 
215   @param  Address Address that encodes the PCI Bus, Device, Function and
216                   Register.
217   @param  AndData The value to AND with the PCI configuration register.
218   @param  OrData  The value to OR with the result of the AND operation.
219 
220   @return The value written back to the PCI configuration register.
221 
222 **/
223 UINT8
224 EFIAPI
S3PciAndThenOr8(IN UINTN Address,IN UINT8 AndData,IN UINT8 OrData)225 S3PciAndThenOr8 (
226   IN UINTN                     Address,
227   IN UINT8                     AndData,
228   IN UINT8                     OrData
229   )
230 {
231   return InternalSavePciWrite8ValueToBootScript (Address, PciAndThenOr8 (Address, AndData, OrData));
232 }
233 
234 /**
235   Reads a bit field of a PCI configuration register and saves the value in
236   the S3 script to be replayed on S3 resume.
237 
238   Reads the bit field in an 8-bit PCI configuration register. The bit field is
239   specified by the StartBit and the EndBit. The value of the bit field is
240   returned.
241 
242   If Address > 0x0FFFFFFF, then ASSERT().
243   If StartBit is greater than 7, then ASSERT().
244   If EndBit is greater than 7, then ASSERT().
245   If EndBit is less than StartBit, then ASSERT().
246 
247   @param  Address   PCI configuration register to read.
248   @param  StartBit  The ordinal of the least significant bit in the bit field.
249                     Range 0..7.
250   @param  EndBit    The ordinal of the most significant bit in the bit field.
251                     Range 0..7.
252 
253   @return The value of the bit field read from the PCI configuration register.
254 
255 **/
256 UINT8
257 EFIAPI
S3PciBitFieldRead8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit)258 S3PciBitFieldRead8 (
259   IN UINTN                     Address,
260   IN UINTN                     StartBit,
261   IN UINTN                     EndBit
262   )
263 {
264   return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldRead8 (Address, StartBit, EndBit));
265 }
266 
267 /**
268   Writes a bit field to a PCI configuration register and saves the value in
269   the S3 script to be replayed on S3 resume.
270 
271   Writes Value to the bit field of the PCI configuration register. The bit
272   field is specified by the StartBit and the EndBit. All other bits in the
273   destination PCI configuration register are preserved. The new value of the
274   8-bit register is returned.
275 
276   If Address > 0x0FFFFFFF, then ASSERT().
277   If StartBit is greater than 7, then ASSERT().
278   If EndBit is greater than 7, then ASSERT().
279   If EndBit is less than StartBit, then ASSERT().
280   If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
281 
282   @param  Address   PCI configuration register to write.
283   @param  StartBit  The ordinal of the least significant bit in the bit field.
284                     Range 0..7.
285   @param  EndBit    The ordinal of the most significant bit in the bit field.
286                     Range 0..7.
287   @param  Value     New value of the bit field.
288 
289   @return The value written back to the PCI configuration register.
290 
291 **/
292 UINT8
293 EFIAPI
S3PciBitFieldWrite8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 Value)294 S3PciBitFieldWrite8 (
295   IN UINTN                     Address,
296   IN UINTN                     StartBit,
297   IN UINTN                     EndBit,
298   IN UINT8                     Value
299   )
300 {
301   return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldWrite8 (Address, StartBit, EndBit, Value));
302 }
303 
304 /**
305   Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
306   writes the result back to the bit field in the 8-bit port and saves the value
307   in the S3 script to be replayed on S3 resume.
308 
309   Reads the 8-bit PCI configuration register specified by Address, performs a
310   bitwise OR between the read result and the value specified by
311   OrData, and writes the result to the 8-bit PCI configuration register
312   specified by Address. The value written to the PCI configuration register is
313   returned. This function must guarantee that all PCI read and write operations
314   are serialized. Extra left bits in OrData are stripped.
315 
316   If Address > 0x0FFFFFFF, then ASSERT().
317   If StartBit is greater than 7, then ASSERT().
318   If EndBit is greater than 7, then ASSERT().
319   If EndBit is less than StartBit, then ASSERT().
320   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
321 
322   @param  Address   PCI configuration register to write.
323   @param  StartBit  The ordinal of the least significant bit in the bit field.
324                     Range 0..7.
325   @param  EndBit    The ordinal of the most significant bit in the bit field.
326                     Range 0..7.
327   @param  OrData    The value to OR with the PCI configuration register.
328 
329   @return The value written back to the PCI configuration register.
330 
331 **/
332 UINT8
333 EFIAPI
S3PciBitFieldOr8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 OrData)334 S3PciBitFieldOr8 (
335   IN UINTN                     Address,
336   IN UINTN                     StartBit,
337   IN UINTN                     EndBit,
338   IN UINT8                     OrData
339   )
340 {
341   return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldOr8 (Address, StartBit, EndBit, OrData));
342 }
343 
344 /**
345   Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
346   AND, and writes the result back to the bit field in the 8-bit register and
347   saves the value in the S3 script to be replayed on S3 resume.
348 
349   Reads the 8-bit PCI configuration register specified by Address, performs a
350   bitwise AND between the read result and the value specified by AndData, and
351   writes the result to the 8-bit PCI configuration register specified by
352   Address. The value written to the PCI configuration register is returned.
353   This function must guarantee that all PCI read and write operations are
354   serialized. Extra left bits in AndData are stripped.
355 
356   If Address > 0x0FFFFFFF, then ASSERT().
357   If StartBit is greater than 7, then ASSERT().
358   If EndBit is greater than 7, then ASSERT().
359   If EndBit is less than StartBit, then ASSERT().
360   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
361 
362   @param  Address   PCI configuration register to write.
363   @param  StartBit  The ordinal of the least significant bit in the bit field.
364                     Range 0..7.
365   @param  EndBit    The ordinal of the most significant bit in the bit field.
366                     Range 0..7.
367   @param  AndData   The value to AND with the PCI configuration register.
368 
369   @return The value written back to the PCI configuration register.
370 
371 **/
372 UINT8
373 EFIAPI
S3PciBitFieldAnd8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 AndData)374 S3PciBitFieldAnd8 (
375   IN UINTN                     Address,
376   IN UINTN                     StartBit,
377   IN UINTN                     EndBit,
378   IN UINT8                     AndData
379   )
380 {
381   return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldAnd8 (Address, StartBit, EndBit, AndData));
382 }
383 
384 /**
385   Reads a bit field in an 8-bit Address, performs a bitwise AND followed by a
386   bitwise OR, and writes the result back to the bit field in the
387   8-bit port and saves the value in the S3 script to be replayed on S3 resume.
388 
389   Reads the 8-bit PCI configuration register specified by Address, performs a
390   bitwise AND followed by a bitwise OR between the read result and
391   the value specified by AndData, and writes the result to the 8-bit PCI
392   configuration register specified by Address. The value written to the PCI
393   configuration register is returned. This function must guarantee that all PCI
394   read and write operations are serialized. Extra left bits in both AndData and
395   OrData are stripped.
396 
397   If Address > 0x0FFFFFFF, then ASSERT().
398   If StartBit is greater than 7, then ASSERT().
399   If EndBit is greater than 7, then ASSERT().
400   If EndBit is less than StartBit, then ASSERT().
401   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
402   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
403 
404   @param  Address   PCI configuration register to write.
405   @param  StartBit  The ordinal of the least significant bit in the bit field.
406                     Range 0..7.
407   @param  EndBit    The ordinal of the most significant bit in the bit field.
408                     Range 0..7.
409   @param  AndData   The value to AND with the PCI configuration register.
410   @param  OrData    The value to OR with the result of the AND operation.
411 
412   @return The value written back to the PCI configuration register.
413 
414 **/
415 UINT8
416 EFIAPI
S3PciBitFieldAndThenOr8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 AndData,IN UINT8 OrData)417 S3PciBitFieldAndThenOr8 (
418   IN UINTN                     Address,
419   IN UINTN                     StartBit,
420   IN UINTN                     EndBit,
421   IN UINT8                     AndData,
422   IN UINT8                     OrData
423   )
424 {
425   return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData));
426 }
427 
428 /**
429   Saves a 16-bit PCI configuration value to the boot script.
430 
431   This internal worker function saves a 16-bit PCI configuration value in
432   the S3 script to be replayed on S3 resume.
433 
434   If the saving process fails, then ASSERT().
435 
436   @param  Address Address that encodes the PCI Bus, Device, Function and
437                   Register.
438   @param  Value   The value to write.
439 
440   @return Value.
441 
442 **/
443 UINT16
InternalSavePciWrite16ValueToBootScript(IN UINTN Address,IN UINT16 Value)444 InternalSavePciWrite16ValueToBootScript (
445   IN UINTN              Address,
446   IN UINT16             Value
447   )
448 {
449   InternalSavePciWriteValueToBootScript (S3BootScriptWidthUint16, Address, &Value);
450 
451   return Value;
452 }
453 
454 /**
455   Reads a 16-bit PCI configuration register and saves the value in the S3
456   script to be replayed on S3 resume.
457 
458   Reads and returns the 16-bit PCI configuration register specified by Address.
459   This function must guarantee that all PCI read and write operations are
460   serialized.
461 
462   If Address > 0x0FFFFFFF, then ASSERT().
463   If Address is not aligned on a 16-bit boundary, then ASSERT().
464 
465   @param  Address Address that encodes the PCI Bus, Device, Function and
466                   Register.
467 
468   @return The read value from the PCI configuration register.
469 
470 **/
471 UINT16
472 EFIAPI
S3PciRead16(IN UINTN Address)473 S3PciRead16 (
474   IN UINTN                     Address
475   )
476 {
477   return InternalSavePciWrite16ValueToBootScript (Address, PciRead16 (Address));
478 }
479 
480 /**
481   Writes a 16-bit PCI configuration register and saves the value in the S3
482   script to be replayed on S3 resume.
483 
484   Writes the 16-bit PCI configuration register specified by Address with the
485   value specified by Value. Value is returned. This function must guarantee
486   that all PCI read and write operations are serialized.
487 
488   If Address > 0x0FFFFFFF, then ASSERT().
489   If Address is not aligned on a 16-bit boundary, then ASSERT().
490 
491   @param  Address Address that encodes the PCI Bus, Device, Function and
492                   Register.
493   @param  Value   The value to write.
494 
495   @return The value written to the PCI configuration register.
496 
497 **/
498 UINT16
499 EFIAPI
S3PciWrite16(IN UINTN Address,IN UINT16 Value)500 S3PciWrite16 (
501   IN UINTN                     Address,
502   IN UINT16                    Value
503   )
504 {
505   return InternalSavePciWrite16ValueToBootScript (Address, PciWrite16 (Address, Value));
506 }
507 
508 /**
509   Performs a bitwise OR of a 16-bit PCI configuration register with
510   a 16-bit value and saves the value in the S3 script to be replayed on S3 resume.
511 
512   Reads the 16-bit PCI configuration register specified by Address, performs a
513   bitwise OR between the read result and the value specified by
514   OrData, and writes the result to the 16-bit PCI configuration register
515   specified by Address. The value written to the PCI configuration register is
516   returned. This function must guarantee that all PCI read and write operations
517   are serialized.
518 
519   If Address > 0x0FFFFFFF, then ASSERT().
520   If Address is not aligned on a 16-bit boundary, then ASSERT().
521 
522   @param  Address Address that encodes the PCI Bus, Device, Function and
523                   Register.
524   @param  OrData  The value to OR with the PCI configuration register.
525 
526   @return The value written back to the PCI configuration register.
527 
528 **/
529 UINT16
530 EFIAPI
S3PciOr16(IN UINTN Address,IN UINT16 OrData)531 S3PciOr16 (
532   IN UINTN                     Address,
533   IN UINT16                    OrData
534   )
535 {
536   return InternalSavePciWrite16ValueToBootScript (Address, PciOr16 (Address, OrData));
537 }
538 
539 /**
540   Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
541   value and saves the value in the S3 script to be replayed on S3 resume.
542 
543   Reads the 16-bit PCI configuration register specified by Address, performs a
544   bitwise AND between the read result and the value specified by AndData, and
545   writes the result to the 16-bit PCI configuration register specified by
546   Address. The value written to the PCI configuration register is returned.
547   This function must guarantee that all PCI read and write operations are
548   serialized.
549 
550   If Address > 0x0FFFFFFF, then ASSERT().
551   If Address is not aligned on a 16-bit boundary, then ASSERT().
552 
553   @param  Address Address that encodes the PCI Bus, Device, Function and
554                   Register.
555   @param  AndData The value to AND with the PCI configuration register.
556 
557   @return The value written back to the PCI configuration register.
558 
559 **/
560 UINT16
561 EFIAPI
S3PciAnd16(IN UINTN Address,IN UINT16 AndData)562 S3PciAnd16 (
563   IN UINTN                     Address,
564   IN UINT16                    AndData
565   )
566 {
567   return InternalSavePciWrite16ValueToBootScript (Address, PciAnd16 (Address, AndData));
568 }
569 
570 /**
571   Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
572   value, followed a  bitwise OR with another 16-bit value and saves
573   the value in the S3 script to be replayed on S3 resume.
574 
575   Reads the 16-bit PCI configuration register specified by Address, performs a
576   bitwise AND between the read result and the value specified by AndData,
577   performs a bitwise OR between the result of the AND operation and
578   the value specified by OrData, and writes the result to the 16-bit PCI
579   configuration register specified by Address. The value written to the PCI
580   configuration register is returned. This function must guarantee that all PCI
581   read and write operations are serialized.
582 
583   If Address > 0x0FFFFFFF, then ASSERT().
584   If Address is not aligned on a 16-bit boundary, then ASSERT().
585 
586   @param  Address Address that encodes the PCI Bus, Device, Function and
587                   Register.
588   @param  AndData The value to AND with the PCI configuration register.
589   @param  OrData  The value to OR with the result of the AND operation.
590 
591   @return The value written back to the PCI configuration register.
592 
593 **/
594 UINT16
595 EFIAPI
S3PciAndThenOr16(IN UINTN Address,IN UINT16 AndData,IN UINT16 OrData)596 S3PciAndThenOr16 (
597   IN UINTN                     Address,
598   IN UINT16                    AndData,
599   IN UINT16                    OrData
600   )
601 {
602   return InternalSavePciWrite16ValueToBootScript (Address, PciAndThenOr16 (Address, AndData, OrData));
603 }
604 
605 /**
606   Reads a bit field of a PCI configuration register and saves the value in
607   the S3 script to be replayed on S3 resume.
608 
609   Reads the bit field in a 16-bit PCI configuration register. The bit field is
610   specified by the StartBit and the EndBit. The value of the bit field is
611   returned.
612 
613   If Address > 0x0FFFFFFF, then ASSERT().
614   If Address is not aligned on a 16-bit boundary, then ASSERT().
615   If StartBit is greater than 15, then ASSERT().
616   If EndBit is greater than 15, then ASSERT().
617   If EndBit is less than StartBit, then ASSERT().
618 
619   @param  Address   PCI configuration register to read.
620   @param  StartBit  The ordinal of the least significant bit in the bit field.
621                     Range 0..15.
622   @param  EndBit    The ordinal of the most significant bit in the bit field.
623                     Range 0..15.
624 
625   @return The value of the bit field read from the PCI configuration register.
626 
627 **/
628 UINT16
629 EFIAPI
S3PciBitFieldRead16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit)630 S3PciBitFieldRead16 (
631   IN UINTN                     Address,
632   IN UINTN                     StartBit,
633   IN UINTN                     EndBit
634   )
635 {
636   return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldRead16 (Address, StartBit, EndBit));
637 }
638 
639 /**
640   Writes a bit field to a PCI configuration register and saves the value in
641   the S3 script to be replayed on S3 resume.
642 
643   Writes Value to the bit field of the PCI configuration register. The bit
644   field is specified by the StartBit and the EndBit. All other bits in the
645   destination PCI configuration register are preserved. The new value of the
646   16-bit register is returned.
647 
648   If Address > 0x0FFFFFFF, then ASSERT().
649   If Address is not aligned on a 16-bit boundary, then ASSERT().
650   If StartBit is greater than 15, then ASSERT().
651   If EndBit is greater than 15, then ASSERT().
652   If EndBit is less than StartBit, then ASSERT().
653   If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
654 
655   @param  Address   PCI configuration register to write.
656   @param  StartBit  The ordinal of the least significant bit in the bit field.
657                     Range 0..15.
658   @param  EndBit    The ordinal of the most significant bit in the bit field.
659                     Range 0..15.
660   @param  Value     New value of the bit field.
661 
662   @return The value written back to the PCI configuration register.
663 
664 **/
665 UINT16
666 EFIAPI
S3PciBitFieldWrite16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 Value)667 S3PciBitFieldWrite16 (
668   IN UINTN                     Address,
669   IN UINTN                     StartBit,
670   IN UINTN                     EndBit,
671   IN UINT16                    Value
672   )
673 {
674   return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldWrite16 (Address, StartBit, EndBit, Value));
675 }
676 
677 /**
678   Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
679   writes the result back to the bit field in the 16-bit port and saves the value
680   in the S3 script to be replayed on S3 resume.
681 
682   Reads the 16-bit PCI configuration register specified by Address, performs a
683   bitwise OR between the read result and the value specified by
684   OrData, and writes the result to the 16-bit PCI configuration register
685   specified by Address. The value written to the PCI configuration register is
686   returned. This function must guarantee that all PCI read and write operations
687   are serialized. Extra left bits in OrData are stripped.
688 
689   If Address > 0x0FFFFFFF, then ASSERT().
690   If Address is not aligned on a 16-bit boundary, then ASSERT().
691   If StartBit is greater than 15, then ASSERT().
692   If EndBit is greater than 15, then ASSERT().
693   If EndBit is less than StartBit, then ASSERT().
694   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
695 
696   @param  Address   PCI configuration register to write.
697   @param  StartBit  The ordinal of the least significant bit in the bit field.
698                     Range 0..15.
699   @param  EndBit    The ordinal of the most significant bit in the bit field.
700                     Range 0..15.
701   @param  OrData    The value to OR with the PCI configuration register.
702 
703   @return The value written back to the PCI configuration register.
704 
705 **/
706 UINT16
707 EFIAPI
S3PciBitFieldOr16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 OrData)708 S3PciBitFieldOr16 (
709   IN UINTN                     Address,
710   IN UINTN                     StartBit,
711   IN UINTN                     EndBit,
712   IN UINT16                    OrData
713   )
714 {
715   return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldOr16 (Address, StartBit, EndBit, OrData));
716 }
717 
718 /**
719   Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
720   AND, and writes the result back to the bit field in the 16-bit register and
721   saves the value in the S3 script to be replayed on S3 resume.
722 
723   Reads the 16-bit PCI configuration register specified by Address, performs a
724   bitwise AND between the read result and the value specified by AndData, and
725   writes the result to the 16-bit PCI configuration register specified by
726   Address. The value written to the PCI configuration register is returned.
727   This function must guarantee that all PCI read and write operations are
728   serialized. Extra left bits in AndData are stripped.
729 
730   If Address > 0x0FFFFFFF, then ASSERT().
731   If Address is not aligned on a 16-bit boundary, then ASSERT().
732   If StartBit is greater than 15, then ASSERT().
733   If EndBit is greater than 15, then ASSERT().
734   If EndBit is less than StartBit, then ASSERT().
735   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
736 
737   @param  Address   PCI configuration register to write.
738   @param  StartBit  The ordinal of the least significant bit in the bit field.
739                     Range 0..15.
740   @param  EndBit    The ordinal of the most significant bit in the bit field.
741                     Range 0..15.
742   @param  AndData   The value to AND with the PCI configuration register.
743 
744   @return The value written back to the PCI configuration register.
745 
746 **/
747 UINT16
748 EFIAPI
S3PciBitFieldAnd16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 AndData)749 S3PciBitFieldAnd16 (
750   IN UINTN                     Address,
751   IN UINTN                     StartBit,
752   IN UINTN                     EndBit,
753   IN UINT16                    AndData
754   )
755 {
756   return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldAnd16 (Address, StartBit, EndBit, AndData));
757 }
758 
759 /**
760   Reads a bit field in a 16-bit Address, performs a bitwise AND followed by a
761   bitwise OR, and writes the result back to the bit field in the
762   16-bit port and saves the value in the S3 script to be replayed on S3 resume.
763 
764   Reads the 16-bit PCI configuration register specified by Address, performs a
765   bitwise AND followed by a bitwise OR between the read result and
766   the value specified by AndData, and writes the result to the 16-bit PCI
767   configuration register specified by Address. The value written to the PCI
768   configuration register is returned. This function must guarantee that all PCI
769   read and write operations are serialized. Extra left bits in both AndData and
770   OrData are stripped.
771 
772   If Address > 0x0FFFFFFF, then ASSERT().
773   If Address is not aligned on a 16-bit boundary, then ASSERT().
774   If StartBit is greater than 15, then ASSERT().
775   If EndBit is greater than 15, then ASSERT().
776   If EndBit is less than StartBit, then ASSERT().
777   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
778   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
779 
780   @param  Address   PCI configuration register to write.
781   @param  StartBit  The ordinal of the least significant bit in the bit field.
782                     Range 0..15.
783   @param  EndBit    The ordinal of the most significant bit in the bit field.
784                     Range 0..15.
785   @param  AndData   The value to AND with the PCI configuration register.
786   @param  OrData    The value to OR with the result of the AND operation.
787 
788   @return The value written back to the PCI configuration register.
789 
790 **/
791 UINT16
792 EFIAPI
S3PciBitFieldAndThenOr16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 AndData,IN UINT16 OrData)793 S3PciBitFieldAndThenOr16 (
794   IN UINTN                     Address,
795   IN UINTN                     StartBit,
796   IN UINTN                     EndBit,
797   IN UINT16                    AndData,
798   IN UINT16                    OrData
799   )
800 {
801   return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData));
802 }
803 
804 /**
805   Saves a 32-bit PCI configuration value to the boot script.
806 
807   This internal worker function saves a 32-bit PCI configuration value in the S3 script
808   to be replayed on S3 resume.
809 
810   If the saving process fails, then ASSERT().
811 
812   @param  Address Address that encodes the PCI Bus, Device, Function and
813                   Register.
814   @param  Value   The value to write.
815 
816   @return Value.
817 
818 **/
819 UINT32
InternalSavePciWrite32ValueToBootScript(IN UINTN Address,IN UINT32 Value)820 InternalSavePciWrite32ValueToBootScript (
821   IN UINTN              Address,
822   IN UINT32             Value
823   )
824 {
825   InternalSavePciWriteValueToBootScript (S3BootScriptWidthUint32, Address, &Value);
826 
827   return Value;
828 }
829 
830 /**
831   Reads a 32-bit PCI configuration register and saves the value in the S3
832   script to be replayed on S3 resume.
833 
834   Reads and returns the 32-bit PCI configuration register specified by Address.
835   This function must guarantee that all PCI read and write operations are
836   serialized.
837 
838   If Address > 0x0FFFFFFF, then ASSERT().
839   If Address is not aligned on a 32-bit boundary, then ASSERT().
840 
841   @param  Address Address that encodes the PCI Bus, Device, Function and
842                   Register.
843 
844   @return The read value from the PCI configuration register.
845 
846 **/
847 UINT32
848 EFIAPI
S3PciRead32(IN UINTN Address)849 S3PciRead32 (
850   IN UINTN                     Address
851   )
852 {
853   return InternalSavePciWrite32ValueToBootScript (Address, PciRead32 (Address));
854 }
855 
856 /**
857   Writes a 32-bit PCI configuration register and saves the value in the S3
858   script to be replayed on S3 resume.
859 
860   Writes the 32-bit PCI configuration register specified by Address with the
861   value specified by Value. Value is returned. This function must guarantee
862   that all PCI read and write operations are serialized.
863 
864   If Address > 0x0FFFFFFF, then ASSERT().
865   If Address is not aligned on a 32-bit boundary, then ASSERT().
866 
867   @param  Address Address that encodes the PCI Bus, Device, Function and
868                   Register.
869   @param  Value   The value to write.
870 
871   @return The value written to the PCI configuration register.
872 
873 **/
874 UINT32
875 EFIAPI
S3PciWrite32(IN UINTN Address,IN UINT32 Value)876 S3PciWrite32 (
877   IN UINTN                     Address,
878   IN UINT32                    Value
879   )
880 {
881   return InternalSavePciWrite32ValueToBootScript (Address, PciWrite32 (Address, Value));
882 }
883 
884 /**
885   Performs a bitwise OR of a 32-bit PCI configuration register with
886   a 32-bit value and saves the value in the S3 script to be replayed on S3 resume.
887 
888   Reads the 32-bit PCI configuration register specified by Address, performs a
889   bitwise OR between the read result and the value specified by
890   OrData, and writes the result to the 32-bit PCI configuration register
891   specified by Address. The value written to the PCI configuration register is
892   returned. This function must guarantee that all PCI read and write operations
893   are serialized.
894 
895   If Address > 0x0FFFFFFF, then ASSERT().
896   If Address is not aligned on a 32-bit boundary, then ASSERT().
897 
898   @param  Address Address that encodes the PCI Bus, Device, Function and
899                   Register.
900   @param  OrData  The value to OR with the PCI configuration register.
901 
902   @return The value written back to the PCI configuration register.
903 
904 **/
905 UINT32
906 EFIAPI
S3PciOr32(IN UINTN Address,IN UINT32 OrData)907 S3PciOr32 (
908   IN UINTN                     Address,
909   IN UINT32                    OrData
910   )
911 {
912   return InternalSavePciWrite32ValueToBootScript (Address, PciOr32 (Address, OrData));
913 }
914 
915 /**
916   Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
917   value and saves the value in the S3 script to be replayed on S3 resume.
918 
919   Reads the 32-bit PCI configuration register specified by Address, performs a
920   bitwise AND between the read result and the value specified by AndData, and
921   writes the result to the 32-bit PCI configuration register specified by
922   Address. The value written to the PCI configuration register is returned.
923   This function must guarantee that all PCI read and write operations are
924   serialized.
925 
926   If Address > 0x0FFFFFFF, then ASSERT().
927   If Address is not aligned on a 32-bit boundary, then ASSERT().
928 
929   @param  Address Address that encodes the PCI Bus, Device, Function and
930                   Register.
931   @param  AndData The value to AND with the PCI configuration register.
932 
933   @return The value written back to the PCI configuration register.
934 
935 **/
936 UINT32
937 EFIAPI
S3PciAnd32(IN UINTN Address,IN UINT32 AndData)938 S3PciAnd32 (
939   IN UINTN                     Address,
940   IN UINT32                    AndData
941   )
942 {
943   return InternalSavePciWrite32ValueToBootScript (Address, PciAnd32 (Address, AndData));
944 }
945 
946 /**
947   Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
948   value, followed a  bitwise OR with another 32-bit value and saves
949   the value in the S3 script to be replayed on S3 resume.
950 
951   Reads the 32-bit PCI configuration register specified by Address, performs a
952   bitwise AND between the read result and the value specified by AndData,
953   performs a bitwise OR between the result of the AND operation and
954   the value specified by OrData, and writes the result to the 32-bit PCI
955   configuration register specified by Address. The value written to the PCI
956   configuration register is returned. This function must guarantee that all PCI
957   read and write operations are serialized.
958 
959   If Address > 0x0FFFFFFF, then ASSERT().
960   If Address is not aligned on a 32-bit boundary, then ASSERT().
961 
962   @param  Address Address that encodes the PCI Bus, Device, Function and
963                   Register.
964   @param  AndData The value to AND with the PCI configuration register.
965   @param  OrData  The value to OR with the result of the AND operation.
966 
967   @return The value written back to the PCI configuration register.
968 
969 **/
970 UINT32
971 EFIAPI
S3PciAndThenOr32(IN UINTN Address,IN UINT32 AndData,IN UINT32 OrData)972 S3PciAndThenOr32 (
973   IN UINTN                     Address,
974   IN UINT32                    AndData,
975   IN UINT32                    OrData
976   )
977 {
978   return InternalSavePciWrite32ValueToBootScript (Address, PciAndThenOr32 (Address, AndData, OrData));
979 }
980 
981 /**
982   Reads a bit field of a PCI configuration register and saves the value in
983   the S3 script to be replayed on S3 resume.
984 
985   Reads the bit field in a 32-bit PCI configuration register. The bit field is
986   specified by the StartBit and the EndBit. The value of the bit field is
987   returned.
988 
989   If Address > 0x0FFFFFFF, then ASSERT().
990   If Address is not aligned on a 32-bit boundary, then ASSERT().
991   If StartBit is greater than 31, then ASSERT().
992   If EndBit is greater than 31, then ASSERT().
993   If EndBit is less than StartBit, then ASSERT().
994 
995   @param  Address   PCI configuration register to read.
996   @param  StartBit  The ordinal of the least significant bit in the bit field.
997                     Range 0..31.
998   @param  EndBit    The ordinal of the most significant bit in the bit field.
999                     Range 0..31.
1000 
1001   @return The value of the bit field read from the PCI configuration register.
1002 
1003 **/
1004 UINT32
1005 EFIAPI
S3PciBitFieldRead32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit)1006 S3PciBitFieldRead32 (
1007   IN UINTN                     Address,
1008   IN UINTN                     StartBit,
1009   IN UINTN                     EndBit
1010   )
1011 {
1012   return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldRead32 (Address, StartBit, EndBit));
1013 }
1014 
1015 /**
1016   Writes a bit field to a PCI configuration register and saves the value in
1017   the S3 script to be replayed on S3 resume.
1018 
1019   Writes Value to the bit field of the PCI configuration register. The bit
1020   field is specified by the StartBit and the EndBit. All other bits in the
1021   destination PCI configuration register are preserved. The new value of the
1022   32-bit register is returned.
1023 
1024   If Address > 0x0FFFFFFF, then ASSERT().
1025   If Address is not aligned on a 32-bit boundary, then ASSERT().
1026   If StartBit is greater than 31, then ASSERT().
1027   If EndBit is greater than 31, then ASSERT().
1028   If EndBit is less than StartBit, then ASSERT().
1029   If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1030 
1031   @param  Address   PCI configuration register to write.
1032   @param  StartBit  The ordinal of the least significant bit in the bit field.
1033                     Range 0..31.
1034   @param  EndBit    The ordinal of the most significant bit in the bit field.
1035                     Range 0..31.
1036   @param  Value     New value of the bit field.
1037 
1038   @return The value written back to the PCI configuration register.
1039 
1040 **/
1041 UINT32
1042 EFIAPI
S3PciBitFieldWrite32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 Value)1043 S3PciBitFieldWrite32 (
1044   IN UINTN                     Address,
1045   IN UINTN                     StartBit,
1046   IN UINTN                     EndBit,
1047   IN UINT32                    Value
1048   )
1049 {
1050   return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldWrite32 (Address, StartBit, EndBit, Value));
1051 }
1052 
1053 /**
1054   Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1055   writes the result back to the bit field in the 32-bit port and saves the value
1056   in the S3 script to be replayed on S3 resume.
1057 
1058   Reads the 32-bit PCI configuration register specified by Address, performs a
1059   bitwise OR between the read result and the value specified by
1060   OrData, and writes the result to the 32-bit PCI configuration register
1061   specified by Address. The value written to the PCI configuration register is
1062   returned. This function must guarantee that all PCI read and write operations
1063   are serialized. Extra left bits in OrData are stripped.
1064 
1065   If Address > 0x0FFFFFFF, then ASSERT().
1066   If Address is not aligned on a 32-bit boundary, then ASSERT().
1067   If StartBit is greater than 31, then ASSERT().
1068   If EndBit is greater than 31, then ASSERT().
1069   If EndBit is less than StartBit, then ASSERT().
1070   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1071 
1072   @param  Address   PCI configuration register to write.
1073   @param  StartBit  The ordinal of the least significant bit in the bit field.
1074                     Range 0..31.
1075   @param  EndBit    The ordinal of the most significant bit in the bit field.
1076                     Range 0..31.
1077   @param  OrData    The value to OR with the PCI configuration register.
1078 
1079   @return The value written back to the PCI configuration register.
1080 
1081 **/
1082 UINT32
1083 EFIAPI
S3PciBitFieldOr32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 OrData)1084 S3PciBitFieldOr32 (
1085   IN UINTN                     Address,
1086   IN UINTN                     StartBit,
1087   IN UINTN                     EndBit,
1088   IN UINT32                    OrData
1089   )
1090 {
1091   return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldOr32 (Address, StartBit, EndBit, OrData));
1092 }
1093 
1094 /**
1095   Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1096   AND, and writes the result back to the bit field in the 32-bit register and
1097   saves the value in the S3 script to be replayed on S3 resume.
1098 
1099   Reads the 32-bit PCI configuration register specified by Address, performs a
1100   bitwise AND between the read result and the value specified by AndData, and
1101   writes the result to the 32-bit PCI configuration register specified by
1102   Address. The value written to the PCI configuration register is returned.
1103   This function must guarantee that all PCI read and write operations are
1104   serialized. Extra left bits in AndData are stripped.
1105 
1106   If Address > 0x0FFFFFFF, then ASSERT().
1107   If Address is not aligned on a 32-bit boundary, then ASSERT().
1108   If StartBit is greater than 31, then ASSERT().
1109   If EndBit is greater than 31, then ASSERT().
1110   If EndBit is less than StartBit, then ASSERT().
1111   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1112 
1113   @param  Address   PCI configuration register to write.
1114   @param  StartBit  The ordinal of the least significant bit in the bit field.
1115                     Range 0..31.
1116   @param  EndBit    The ordinal of the most significant bit in the bit field.
1117                     Range 0..31.
1118   @param  AndData   The value to AND with the PCI configuration register.
1119 
1120   @return The value written back to the PCI configuration register.
1121 
1122 **/
1123 UINT32
1124 EFIAPI
S3PciBitFieldAnd32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 AndData)1125 S3PciBitFieldAnd32 (
1126   IN UINTN                     Address,
1127   IN UINTN                     StartBit,
1128   IN UINTN                     EndBit,
1129   IN UINT32                    AndData
1130   )
1131 {
1132   return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldAnd32 (Address, StartBit, EndBit, AndData));
1133 }
1134 
1135 /**
1136   Reads a bit field in a 32-bit Address, performs a bitwise AND followed by a
1137   bitwise OR, and writes the result back to the bit field in the
1138   32-bit port and saves the value in the S3 script to be replayed on S3 resume.
1139 
1140   Reads the 32-bit PCI configuration register specified by Address, performs a
1141   bitwise AND followed by a bitwise OR between the read result and
1142   the value specified by AndData, and writes the result to the 32-bit PCI
1143   configuration register specified by Address. The value written to the PCI
1144   configuration register is returned. This function must guarantee that all PCI
1145   read and write operations are serialized. Extra left bits in both AndData and
1146   OrData are stripped.
1147 
1148   If Address > 0x0FFFFFFF, then ASSERT().
1149   If Address is not aligned on a 32-bit boundary, then ASSERT().
1150   If StartBit is greater than 31, then ASSERT().
1151   If EndBit is greater than 31, then ASSERT().
1152   If EndBit is less than StartBit, then ASSERT().
1153   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1154   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1155 
1156   @param  Address   PCI configuration register to write.
1157   @param  StartBit  The ordinal of the least significant bit in the bit field.
1158                     Range 0..31.
1159   @param  EndBit    The ordinal of the most significant bit in the bit field.
1160                     Range 0..31.
1161   @param  AndData   The value to AND with the PCI configuration register.
1162   @param  OrData    The value to OR with the result of the AND operation.
1163 
1164   @return The value written back to the PCI configuration register.
1165 
1166 **/
1167 UINT32
1168 EFIAPI
S3PciBitFieldAndThenOr32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 AndData,IN UINT32 OrData)1169 S3PciBitFieldAndThenOr32 (
1170   IN UINTN                     Address,
1171   IN UINTN                     StartBit,
1172   IN UINTN                     EndBit,
1173   IN UINT32                    AndData,
1174   IN UINT32                    OrData
1175   )
1176 {
1177   return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData));
1178 }
1179 
1180 /**
1181   Reads a range of PCI configuration registers into a caller supplied buffer
1182   and saves the value in the S3 script to be replayed on S3 resume.
1183 
1184   Reads the range of PCI configuration registers specified by StartAddress and
1185   Size into the buffer specified by Buffer. This function only allows the PCI
1186   configuration registers from a single PCI function to be read. Size is
1187   returned. When possible 32-bit PCI configuration read cycles are used to read
1188   from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1189   and 16-bit PCI configuration read cycles may be used at the beginning and the
1190   end of the range.
1191 
1192   If StartAddress > 0x0FFFFFFF, then ASSERT().
1193   If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1194   If Size > 0 and Buffer is NULL, then ASSERT().
1195 
1196   @param  StartAddress  Starting address that encodes the PCI Bus, Device,
1197                         Function and Register.
1198   @param  Size          Size in bytes of the transfer.
1199   @param  Buffer        Pointer to a buffer receiving the data read.
1200 
1201   @return Size
1202 
1203 **/
1204 UINTN
1205 EFIAPI
S3PciReadBuffer(IN UINTN StartAddress,IN UINTN Size,OUT VOID * Buffer)1206 S3PciReadBuffer (
1207   IN  UINTN                    StartAddress,
1208   IN  UINTN                    Size,
1209   OUT VOID                     *Buffer
1210   )
1211 {
1212   RETURN_STATUS    Status;
1213 
1214   Status = S3BootScriptSavePciCfgWrite (
1215              S3BootScriptWidthUint8,
1216              PCILIB_TO_COMMON_ADDRESS (StartAddress),
1217              PciReadBuffer (StartAddress, Size, Buffer),
1218              Buffer
1219              );
1220  ASSERT (Status == RETURN_SUCCESS);
1221 
1222   return Size;
1223 }
1224 
1225 /**
1226   Copies the data in a caller supplied buffer to a specified range of PCI
1227   configuration space and saves the value in the S3 script to be replayed on S3
1228   resume.
1229 
1230   Writes the range of PCI configuration registers specified by StartAddress and
1231   Size from the buffer specified by Buffer. This function only allows the PCI
1232   configuration registers from a single PCI function to be written. Size is
1233   returned. When possible 32-bit PCI configuration write cycles are used to
1234   write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1235   8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1236   and the end of the range.
1237 
1238   If StartAddress > 0x0FFFFFFF, then ASSERT().
1239   If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1240   If Size > 0 and Buffer is NULL, then ASSERT().
1241 
1242   @param  StartAddress  Starting address that encodes the PCI Bus, Device,
1243                         Function and Register.
1244   @param  Size          Size in bytes of the transfer.
1245   @param  Buffer        Pointer to a buffer containing the data to write.
1246 
1247   @return Size
1248 
1249 **/
1250 UINTN
1251 EFIAPI
S3PciWriteBuffer(IN UINTN StartAddress,IN UINTN Size,IN VOID * Buffer)1252 S3PciWriteBuffer (
1253   IN UINTN                     StartAddress,
1254   IN UINTN                     Size,
1255   IN VOID                      *Buffer
1256   )
1257 {
1258   RETURN_STATUS    Status;
1259 
1260   Status = S3BootScriptSavePciCfgWrite (
1261              S3BootScriptWidthUint8,
1262              PCILIB_TO_COMMON_ADDRESS (StartAddress),
1263              PciWriteBuffer (StartAddress, Size, Buffer),
1264              Buffer
1265              );
1266   ASSERT (Status == RETURN_SUCCESS);
1267 
1268   return Size;
1269 }
1270