Home | History | Annotate | Download | only in BaseS3PciLib
      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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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