• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   PCI Library using PCI CFG2 PPI.
3 
4   Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
5   This program and the accompanying materials are
6   licensed and made available under the terms and conditions of
7   the BSD License which accompanies this distribution.  The full
8   text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php.
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include <PiPei.h>
17 
18 #include <Ppi/PciCfg2.h>
19 
20 #include <Library/PciLib.h>
21 #include <Library/BaseLib.h>
22 #include <Library/PeiServicesTablePointerLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/PeiServicesLib.h>
25 
26 /**
27   Assert the validity of a PCI address. A valid PCI address should contain 1's
28   only in the low 28 bits.
29 
30   @param  A The address to validate.
31   @param  M Additional bits to assert to be zero.
32 
33 **/
34 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
35   ASSERT (((A) & (~0xfffffff | (M))) == 0)
36 
37 /**
38   Translate PCI Lib address into format of PCI CFG2 PPI.
39 
40   @param  A  The address that encodes the PCI Bus, Device, Function and
41              Register.
42 
43 **/
44 #define PCI_TO_PCICFG2_ADDRESS(A) \
45   ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))
46 
47 /**
48   Internal worker function to read a PCI configuration register.
49 
50   This function wraps EFI_PEI_PCI_CFG2_PPI.Read() service.
51   It reads and returns the PCI configuration register specified by Address,
52   the width of data is specified by Width.
53 
54   @param  Address The address that encodes the PCI Bus, Device, Function and
55                   Register.
56   @param  Width   The width of data to read
57 
58   @return The value read from the PCI configuration register.
59 
60 **/
61 UINT32
PeiPciLibPciCfg2ReadWorker(IN UINTN Address,IN EFI_PEI_PCI_CFG_PPI_WIDTH Width)62 PeiPciLibPciCfg2ReadWorker (
63   IN    UINTN                       Address,
64   IN    EFI_PEI_PCI_CFG_PPI_WIDTH   Width
65   )
66 {
67   EFI_STATUS                   Status;
68   UINT32                       Data;
69   CONST EFI_PEI_PCI_CFG2_PPI   *PciCfg2Ppi;
70   UINT64                       PciCfg2Address;
71 
72   Status = PeiServicesLocatePpi (&gEfiPciCfg2PpiGuid, 0, NULL, (VOID **) &PciCfg2Ppi);
73   ASSERT_EFI_ERROR (Status);
74   ASSERT (PciCfg2Ppi != NULL);
75 
76   PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address);
77   PciCfg2Ppi->Read (
78                 GetPeiServicesTablePointer (),
79                 PciCfg2Ppi,
80                 Width,
81                 PciCfg2Address,
82                 &Data
83                 );
84 
85   return Data;
86 }
87 
88 /**
89   Internal worker function to writes a PCI configuration register.
90 
91   This function wraps EFI_PEI_PCI_CFG2_PPI.Write() service.
92   It writes the PCI configuration register specified by Address with the
93   value specified by Data. The width of data is specifed by Width.
94   Data is returned.
95 
96   @param  Address The address that encodes the PCI Bus, Device, Function and
97                   Register.
98   @param  Width   The width of data to write
99   @param  Data    The value to write.
100 
101   @return The value written to the PCI configuration register.
102 
103 **/
104 UINT32
PeiPciLibPciCfg2WriteWorker(IN UINTN Address,IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,IN UINT32 Data)105 PeiPciLibPciCfg2WriteWorker (
106   IN    UINTN                       Address,
107   IN    EFI_PEI_PCI_CFG_PPI_WIDTH   Width,
108   IN    UINT32                      Data
109   )
110 {
111   EFI_STATUS                      Status;
112   CONST EFI_PEI_PCI_CFG2_PPI      *PciCfg2Ppi;
113   UINT64                          PciCfg2Address;
114 
115   Status = PeiServicesLocatePpi (&gEfiPciCfg2PpiGuid, 0, NULL, (VOID **) &PciCfg2Ppi);
116   ASSERT_EFI_ERROR (Status);
117   ASSERT (PciCfg2Ppi != NULL);
118 
119   PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address);
120   PciCfg2Ppi->Write (
121                 GetPeiServicesTablePointer (),
122                 PciCfg2Ppi,
123                 Width,
124                 PciCfg2Address,
125                 &Data
126                 );
127 
128   return Data;
129 }
130 
131 /**
132   Registers a PCI device so PCI configuration registers may be accessed after
133   SetVirtualAddressMap().
134 
135   Registers the PCI device specified by Address so all the PCI configuration registers
136   associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
137 
138   If Address > 0x0FFFFFFF, then ASSERT().
139 
140   @param  Address The address that encodes the PCI Bus, Device, Function and
141                   Register.
142 
143   @retval RETURN_SUCCESS           The PCI device was registered for runtime access.
144   @retval RETURN_UNSUPPORTED       An attempt was made to call this function
145                                    after ExitBootServices().
146   @retval RETURN_UNSUPPORTED       The resources required to access the PCI device
147                                    at runtime could not be mapped.
148   @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to
149                                    complete the registration.
150 
151 **/
152 RETURN_STATUS
153 EFIAPI
PciRegisterForRuntimeAccess(IN UINTN Address)154 PciRegisterForRuntimeAccess (
155   IN UINTN  Address
156   )
157 {
158   ASSERT_INVALID_PCI_ADDRESS (Address, 0);
159   return RETURN_UNSUPPORTED;
160 }
161 
162 /**
163   Reads an 8-bit PCI configuration register.
164 
165   Reads and returns the 8-bit PCI configuration register specified by Address.
166   This function must guarantee that all PCI read and write operations are
167   serialized.
168 
169   If Address > 0x0FFFFFFF, then ASSERT().
170 
171   @param  Address The address that encodes the PCI Bus, Device, Function and
172                   Register.
173 
174   @return The read value from the PCI configuration register.
175 
176 **/
177 UINT8
178 EFIAPI
PciRead8(IN UINTN Address)179 PciRead8 (
180   IN      UINTN                     Address
181   )
182 {
183   ASSERT_INVALID_PCI_ADDRESS (Address, 0);
184 
185   return (UINT8) PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint8);
186 }
187 
188 /**
189   Writes an 8-bit PCI configuration register.
190 
191   Writes the 8-bit PCI configuration register specified by Address with the
192   value specified by Value. Value is returned. This function must guarantee
193   that all PCI read and write operations are serialized.
194 
195   If Address > 0x0FFFFFFF, then ASSERT().
196 
197   @param  Address The address that encodes the PCI Bus, Device, Function and
198                   Register.
199   @param  Value   The value to write.
200 
201   @return The value written to the PCI configuration register.
202 
203 **/
204 UINT8
205 EFIAPI
PciWrite8(IN UINTN Address,IN UINT8 Value)206 PciWrite8 (
207   IN      UINTN                     Address,
208   IN      UINT8                     Value
209   )
210 {
211   ASSERT_INVALID_PCI_ADDRESS (Address, 0);
212 
213   return (UINT8) PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint8, Value);
214 }
215 
216 /**
217   Performs a bitwise OR of an 8-bit PCI configuration register with
218   an 8-bit value.
219 
220   Reads the 8-bit PCI configuration register specified by Address, performs a
221   bitwise OR between the read result and the value specified by
222   OrData, and writes the result to the 8-bit PCI configuration register
223   specified by Address. The value written to the PCI configuration register is
224   returned. This function must guarantee that all PCI read and write operations
225   are serialized.
226 
227   If Address > 0x0FFFFFFF, then ASSERT().
228 
229   @param  Address The address that encodes the PCI Bus, Device, Function and
230                   Register.
231   @param  OrData  The value to OR with the PCI configuration register.
232 
233   @return The value written back to the PCI configuration register.
234 
235 **/
236 UINT8
237 EFIAPI
PciOr8(IN UINTN Address,IN UINT8 OrData)238 PciOr8 (
239   IN      UINTN                     Address,
240   IN      UINT8                     OrData
241   )
242 {
243   return PciWrite8 (Address, (UINT8) (PciRead8 (Address) | OrData));
244 }
245 
246 /**
247   Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
248   value.
249 
250   Reads the 8-bit PCI configuration register specified by Address, performs a
251   bitwise AND between the read result and the value specified by AndData, and
252   writes the result to the 8-bit PCI configuration register specified by
253   Address. The value written to the PCI configuration register is returned.
254   This function must guarantee that all PCI read and write operations are
255   serialized.
256 
257   If Address > 0x0FFFFFFF, then ASSERT().
258 
259   @param  Address The address that encodes the PCI Bus, Device, Function and
260                   Register.
261   @param  AndData The value to AND with the PCI configuration register.
262 
263   @return The value written back to the PCI configuration register.
264 
265 **/
266 UINT8
267 EFIAPI
PciAnd8(IN UINTN Address,IN UINT8 AndData)268 PciAnd8 (
269   IN      UINTN                     Address,
270   IN      UINT8                     AndData
271   )
272 {
273   return PciWrite8 (Address, (UINT8) (PciRead8 (Address) & AndData));
274 }
275 
276 /**
277   Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
278   value, followed a  bitwise OR with another 8-bit value.
279 
280   Reads the 8-bit PCI configuration register specified by Address, performs a
281   bitwise AND between the read result and the value specified by AndData,
282   performs a bitwise OR between the result of the AND operation and
283   the value specified by OrData, and writes the result to the 8-bit PCI
284   configuration register specified by Address. The value written to the PCI
285   configuration register is returned. This function must guarantee that all PCI
286   read and write operations are serialized.
287 
288   If Address > 0x0FFFFFFF, then ASSERT().
289 
290   @param  Address The address that encodes the PCI Bus, Device, Function and
291                   Register.
292   @param  AndData The value to AND with the PCI configuration register.
293   @param  OrData  The value to OR with the result of the AND operation.
294 
295   @return The value written back to the PCI configuration register.
296 
297 **/
298 UINT8
299 EFIAPI
PciAndThenOr8(IN UINTN Address,IN UINT8 AndData,IN UINT8 OrData)300 PciAndThenOr8 (
301   IN      UINTN                     Address,
302   IN      UINT8                     AndData,
303   IN      UINT8                     OrData
304   )
305 {
306   return PciWrite8 (Address, (UINT8) ((PciRead8 (Address) & AndData) | OrData));
307 }
308 
309 /**
310   Reads a bit field of a PCI configuration register.
311 
312   Reads the bit field in an 8-bit PCI configuration register. The bit field is
313   specified by the StartBit and the EndBit. The value of the bit field is
314   returned.
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 
321   @param  Address   The PCI configuration register to read.
322   @param  StartBit  The ordinal of the least significant bit in the bit field.
323                     Range 0..7.
324   @param  EndBit    The ordinal of the most significant bit in the bit field.
325                     Range 0..7.
326 
327   @return The value of the bit field read from the PCI configuration register.
328 
329 **/
330 UINT8
331 EFIAPI
PciBitFieldRead8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit)332 PciBitFieldRead8 (
333   IN      UINTN                     Address,
334   IN      UINTN                     StartBit,
335   IN      UINTN                     EndBit
336   )
337 {
338   return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);
339 }
340 
341 /**
342   Writes a bit field to a PCI configuration register.
343 
344   Writes Value to the bit field of the PCI configuration register. The bit
345   field is specified by the StartBit and the EndBit. All other bits in the
346   destination PCI configuration register are preserved. The new value of the
347   8-bit register is returned.
348 
349   If Address > 0x0FFFFFFF, then ASSERT().
350   If StartBit is greater than 7, then ASSERT().
351   If EndBit is greater than 7, then ASSERT().
352   If EndBit is less than StartBit, then ASSERT().
353   If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
354 
355   @param  Address   The PCI configuration register to write.
356   @param  StartBit  The ordinal of the least significant bit in the bit field.
357                     Range 0..7.
358   @param  EndBit    The ordinal of the most significant bit in the bit field.
359                     Range 0..7.
360   @param  Value     The new value of the bit field.
361 
362   @return The value written back to the PCI configuration register.
363 
364 **/
365 UINT8
366 EFIAPI
PciBitFieldWrite8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 Value)367 PciBitFieldWrite8 (
368   IN      UINTN                     Address,
369   IN      UINTN                     StartBit,
370   IN      UINTN                     EndBit,
371   IN      UINT8                     Value
372   )
373 {
374   return PciWrite8 (
375            Address,
376            BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)
377            );
378 }
379 
380 /**
381   Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
382   writes the result back to the bit field in the 8-bit port.
383 
384   Reads the 8-bit PCI configuration register specified by Address, performs a
385   bitwise OR between the read result and the value specified by
386   OrData, and writes the result to the 8-bit PCI configuration register
387   specified by Address. The value written to the PCI configuration register is
388   returned. This function must guarantee that all PCI read and write operations
389   are serialized. Extra left bits in OrData are stripped.
390 
391   If Address > 0x0FFFFFFF, then ASSERT().
392   If StartBit is greater than 7, then ASSERT().
393   If EndBit is greater than 7, then ASSERT().
394   If EndBit is less than StartBit, then ASSERT().
395   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
396 
397   @param  Address   The PCI configuration register to write.
398   @param  StartBit  The ordinal of the least significant bit in the bit field.
399                     Range 0..7.
400   @param  EndBit    The ordinal of the most significant bit in the bit field.
401                     Range 0..7.
402   @param  OrData    The value to OR with the PCI configuration register.
403 
404   @return The value written back to the PCI configuration register.
405 
406 **/
407 UINT8
408 EFIAPI
PciBitFieldOr8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 OrData)409 PciBitFieldOr8 (
410   IN      UINTN                     Address,
411   IN      UINTN                     StartBit,
412   IN      UINTN                     EndBit,
413   IN      UINT8                     OrData
414   )
415 {
416   return PciWrite8 (
417            Address,
418            BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)
419            );
420 }
421 
422 /**
423   Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
424   AND, and writes the result back to the bit field in the 8-bit register.
425 
426   Reads the 8-bit PCI configuration register specified by Address, performs a
427   bitwise AND between the read result and the value specified by AndData, and
428   writes the result to the 8-bit PCI configuration register specified by
429   Address. The value written to the PCI configuration register is returned.
430   This function must guarantee that all PCI read and write operations are
431   serialized. Extra left bits in AndData are stripped.
432 
433   If Address > 0x0FFFFFFF, then ASSERT().
434   If StartBit is greater than 7, then ASSERT().
435   If EndBit is greater than 7, then ASSERT().
436   If EndBit is less than StartBit, then ASSERT().
437   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
438 
439   @param  Address   The PCI configuration register to write.
440   @param  StartBit  The ordinal of the least significant bit in the bit field.
441                     Range 0..7.
442   @param  EndBit    The ordinal of the most significant bit in the bit field.
443                     Range 0..7.
444   @param  AndData   The value to AND with the PCI configuration register.
445 
446   @return The value written back to the PCI configuration register.
447 
448 **/
449 UINT8
450 EFIAPI
PciBitFieldAnd8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 AndData)451 PciBitFieldAnd8 (
452   IN      UINTN                     Address,
453   IN      UINTN                     StartBit,
454   IN      UINTN                     EndBit,
455   IN      UINT8                     AndData
456   )
457 {
458   return PciWrite8 (
459            Address,
460            BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)
461            );
462 }
463 
464 /**
465   Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
466   bitwise OR, and writes the result back to the bit field in the
467   8-bit port.
468 
469   Reads the 8-bit PCI configuration register specified by Address, performs a
470   bitwise AND followed by a bitwise OR between the read result and
471   the value specified by AndData, and writes the result to the 8-bit PCI
472   configuration register specified by Address. The value written to the PCI
473   configuration register is returned. This function must guarantee that all PCI
474   read and write operations are serialized. Extra left bits in both AndData and
475   OrData are stripped.
476 
477   If Address > 0x0FFFFFFF, then ASSERT().
478   If StartBit is greater than 7, then ASSERT().
479   If EndBit is greater than 7, then ASSERT().
480   If EndBit is less than StartBit, then ASSERT().
481   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
482   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
483 
484   @param  Address   The PCI configuration register to write.
485   @param  StartBit  The ordinal of the least significant bit in the bit field.
486                     Range 0..7.
487   @param  EndBit    The ordinal of the most significant bit in the bit field.
488                     Range 0..7.
489   @param  AndData   The value to AND with the PCI configuration register.
490   @param  OrData    The value to OR with the result of the AND operation.
491 
492   @return The value written back to the PCI configuration register.
493 
494 **/
495 UINT8
496 EFIAPI
PciBitFieldAndThenOr8(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 AndData,IN UINT8 OrData)497 PciBitFieldAndThenOr8 (
498   IN      UINTN                     Address,
499   IN      UINTN                     StartBit,
500   IN      UINTN                     EndBit,
501   IN      UINT8                     AndData,
502   IN      UINT8                     OrData
503   )
504 {
505   return PciWrite8 (
506            Address,
507            BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)
508            );
509 }
510 
511 /**
512   Reads a 16-bit PCI configuration register.
513 
514   Reads and returns the 16-bit PCI configuration register specified by Address.
515   This function must guarantee that all PCI read and write operations are
516   serialized.
517 
518   If Address > 0x0FFFFFFF, then ASSERT().
519   If Address is not aligned on a 16-bit boundary, then ASSERT().
520 
521   @param  Address The address that encodes the PCI Bus, Device, Function and
522                   Register.
523 
524   @return The read value from the PCI configuration register.
525 
526 **/
527 UINT16
528 EFIAPI
PciRead16(IN UINTN Address)529 PciRead16 (
530   IN      UINTN                     Address
531   )
532 {
533   ASSERT_INVALID_PCI_ADDRESS (Address, 1);
534 
535   return (UINT16) PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint16);
536 }
537 
538 /**
539   Writes a 16-bit PCI configuration register.
540 
541   Writes the 16-bit PCI configuration register specified by Address with the
542   value specified by Value. Value is returned. This function must guarantee
543   that all PCI read and write operations are serialized.
544 
545   If Address > 0x0FFFFFFF, then ASSERT().
546   If Address is not aligned on a 16-bit boundary, then ASSERT().
547 
548   @param  Address The address that encodes the PCI Bus, Device, Function and
549                   Register.
550   @param  Value   The value to write.
551 
552   @return The value written to the PCI configuration register.
553 
554 **/
555 UINT16
556 EFIAPI
PciWrite16(IN UINTN Address,IN UINT16 Value)557 PciWrite16 (
558   IN      UINTN                     Address,
559   IN      UINT16                    Value
560   )
561 {
562   ASSERT_INVALID_PCI_ADDRESS (Address, 1);
563 
564   return (UINT16) PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint16, Value);
565 }
566 
567 /**
568   Performs a bitwise OR of a 16-bit PCI configuration register with
569   a 16-bit value.
570 
571   Reads the 16-bit PCI configuration register specified by Address, performs a
572   bitwise OR between the read result and the value specified by
573   OrData, and writes the result to the 16-bit PCI configuration register
574   specified by Address. The value written to the PCI configuration register is
575   returned. This function must guarantee that all PCI read and write operations
576   are serialized.
577 
578   If Address > 0x0FFFFFFF, then ASSERT().
579   If Address is not aligned on a 16-bit boundary, then ASSERT().
580 
581   @param  Address The address that encodes the PCI Bus, Device, Function and
582                   Register.
583   @param  OrData  The value to OR with the PCI configuration register.
584 
585   @return The value written back to the PCI configuration register.
586 
587 **/
588 UINT16
589 EFIAPI
PciOr16(IN UINTN Address,IN UINT16 OrData)590 PciOr16 (
591   IN      UINTN                     Address,
592   IN      UINT16                    OrData
593   )
594 {
595   return PciWrite16 (Address, (UINT16) (PciRead16 (Address) | OrData));
596 }
597 
598 /**
599   Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
600   value.
601 
602   Reads the 16-bit PCI configuration register specified by Address, performs a
603   bitwise AND between the read result and the value specified by AndData, and
604   writes the result to the 16-bit PCI configuration register specified by
605   Address. The value written to the PCI configuration register is returned.
606   This function must guarantee that all PCI read and write operations are
607   serialized.
608 
609   If Address > 0x0FFFFFFF, then ASSERT().
610   If Address is not aligned on a 16-bit boundary, then ASSERT().
611 
612   @param  Address The address that encodes the PCI Bus, Device, Function and
613                   Register.
614   @param  AndData The value to AND with the PCI configuration register.
615 
616   @return The value written back to the PCI configuration register.
617 
618 **/
619 UINT16
620 EFIAPI
PciAnd16(IN UINTN Address,IN UINT16 AndData)621 PciAnd16 (
622   IN      UINTN                     Address,
623   IN      UINT16                    AndData
624   )
625 {
626   return PciWrite16 (Address, (UINT16) (PciRead16 (Address) & AndData));
627 }
628 
629 /**
630   Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
631   value, followed a  bitwise OR with another 16-bit value.
632 
633   Reads the 16-bit PCI configuration register specified by Address, performs a
634   bitwise AND between the read result and the value specified by AndData,
635   performs a bitwise OR between the result of the AND operation and
636   the value specified by OrData, and writes the result to the 16-bit PCI
637   configuration register specified by Address. The value written to the PCI
638   configuration register is returned. This function must guarantee that all PCI
639   read and write operations are serialized.
640 
641   If Address > 0x0FFFFFFF, then ASSERT().
642   If Address is not aligned on a 16-bit boundary, then ASSERT().
643 
644   @param  Address The address that encodes the PCI Bus, Device, Function and
645                   Register.
646   @param  AndData The value to AND with the PCI configuration register.
647   @param  OrData  The value to OR with the result of the AND operation.
648 
649   @return The value written back to the PCI configuration register.
650 
651 **/
652 UINT16
653 EFIAPI
PciAndThenOr16(IN UINTN Address,IN UINT16 AndData,IN UINT16 OrData)654 PciAndThenOr16 (
655   IN      UINTN                     Address,
656   IN      UINT16                    AndData,
657   IN      UINT16                    OrData
658   )
659 {
660   return PciWrite16 (Address, (UINT16) ((PciRead16 (Address) & AndData) | OrData));
661 }
662 
663 /**
664   Reads a bit field of a PCI configuration register.
665 
666   Reads the bit field in a 16-bit PCI configuration register. The bit field is
667   specified by the StartBit and the EndBit. The value of the bit field is
668   returned.
669 
670   If Address > 0x0FFFFFFF, then ASSERT().
671   If Address is not aligned on a 16-bit boundary, then ASSERT().
672   If StartBit is greater than 15, then ASSERT().
673   If EndBit is greater than 15, then ASSERT().
674   If EndBit is less than StartBit, then ASSERT().
675 
676   @param  Address   The PCI configuration register to read.
677   @param  StartBit  The ordinal of the least significant bit in the bit field.
678                     Range 0..15.
679   @param  EndBit    The ordinal of the most significant bit in the bit field.
680                     Range 0..15.
681 
682   @return The value of the bit field read from the PCI configuration register.
683 
684 **/
685 UINT16
686 EFIAPI
PciBitFieldRead16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit)687 PciBitFieldRead16 (
688   IN      UINTN                     Address,
689   IN      UINTN                     StartBit,
690   IN      UINTN                     EndBit
691   )
692 {
693   return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);
694 }
695 
696 /**
697   Writes a bit field to a PCI configuration register.
698 
699   Writes Value to the bit field of the PCI configuration register. The bit
700   field is specified by the StartBit and the EndBit. All other bits in the
701   destination PCI configuration register are preserved. The new value of the
702   16-bit register is returned.
703 
704   If Address > 0x0FFFFFFF, then ASSERT().
705   If Address is not aligned on a 16-bit boundary, then ASSERT().
706   If StartBit is greater than 15, then ASSERT().
707   If EndBit is greater than 15, then ASSERT().
708   If EndBit is less than StartBit, then ASSERT().
709   If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
710 
711   @param  Address   The PCI configuration register to write.
712   @param  StartBit  The ordinal of the least significant bit in the bit field.
713                     Range 0..15.
714   @param  EndBit    The ordinal of the most significant bit in the bit field.
715                     Range 0..15.
716   @param  Value     The new value of the bit field.
717 
718   @return The value written back to the PCI configuration register.
719 
720 **/
721 UINT16
722 EFIAPI
PciBitFieldWrite16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 Value)723 PciBitFieldWrite16 (
724   IN      UINTN                     Address,
725   IN      UINTN                     StartBit,
726   IN      UINTN                     EndBit,
727   IN      UINT16                    Value
728   )
729 {
730   return PciWrite16 (
731            Address,
732            BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)
733            );
734 }
735 
736 /**
737   Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
738   writes the result back to the bit field in the 16-bit port.
739 
740   Reads the 16-bit PCI configuration register specified by Address, performs a
741   bitwise OR between the read result and the value specified by
742   OrData, and writes the result to the 16-bit PCI configuration register
743   specified by Address. The value written to the PCI configuration register is
744   returned. This function must guarantee that all PCI read and write operations
745   are serialized. Extra left bits in OrData are stripped.
746 
747   If Address > 0x0FFFFFFF, then ASSERT().
748   If Address is not aligned on a 16-bit boundary, then ASSERT().
749   If StartBit is greater than 15, then ASSERT().
750   If EndBit is greater than 15, then ASSERT().
751   If EndBit is less than StartBit, then ASSERT().
752   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
753 
754   @param  Address   The PCI configuration register to write.
755   @param  StartBit  The ordinal of the least significant bit in the bit field.
756                     Range 0..15.
757   @param  EndBit    The ordinal of the most significant bit in the bit field.
758                     Range 0..15.
759   @param  OrData    The value to OR with the PCI configuration register.
760 
761   @return The value written back to the PCI configuration register.
762 
763 **/
764 UINT16
765 EFIAPI
PciBitFieldOr16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 OrData)766 PciBitFieldOr16 (
767   IN      UINTN                     Address,
768   IN      UINTN                     StartBit,
769   IN      UINTN                     EndBit,
770   IN      UINT16                    OrData
771   )
772 {
773   return PciWrite16 (
774            Address,
775            BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)
776            );
777 }
778 
779 /**
780   Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
781   AND, and writes the result back to the bit field in the 16-bit register.
782 
783   Reads the 16-bit PCI configuration register specified by Address, performs a
784   bitwise AND between the read result and the value specified by AndData, and
785   writes the result to the 16-bit PCI configuration register specified by
786   Address. The value written to the PCI configuration register is returned.
787   This function must guarantee that all PCI read and write operations are
788   serialized. Extra left bits in AndData are stripped.
789 
790   If Address > 0x0FFFFFFF, then ASSERT().
791   If Address is not aligned on a 16-bit boundary, then ASSERT().
792   If StartBit is greater than 15, then ASSERT().
793   If EndBit is greater than 15, then ASSERT().
794   If EndBit is less than StartBit, then ASSERT().
795   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
796 
797   @param  Address   The PCI configuration register to write.
798   @param  StartBit  The ordinal of the least significant bit in the bit field.
799                     Range 0..15.
800   @param  EndBit    The ordinal of the most significant bit in the bit field.
801                     Range 0..15.
802   @param  AndData   The value to AND with the PCI configuration register.
803 
804   @return The value written back to the PCI configuration register.
805 
806 **/
807 UINT16
808 EFIAPI
PciBitFieldAnd16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 AndData)809 PciBitFieldAnd16 (
810   IN      UINTN                     Address,
811   IN      UINTN                     StartBit,
812   IN      UINTN                     EndBit,
813   IN      UINT16                    AndData
814   )
815 {
816   return PciWrite16 (
817            Address,
818            BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)
819            );
820 }
821 
822 /**
823   Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
824   bitwise OR, and writes the result back to the bit field in the
825   16-bit port.
826 
827   Reads the 16-bit PCI configuration register specified by Address, performs a
828   bitwise AND followed by a bitwise OR between the read result and
829   the value specified by AndData, and writes the result to the 16-bit PCI
830   configuration register specified by Address. The value written to the PCI
831   configuration register is returned. This function must guarantee that all PCI
832   read and write operations are serialized. Extra left bits in both AndData and
833   OrData are stripped.
834 
835   If Address > 0x0FFFFFFF, then ASSERT().
836   If Address is not aligned on a 16-bit boundary, then ASSERT().
837   If StartBit is greater than 15, then ASSERT().
838   If EndBit is greater than 15, then ASSERT().
839   If EndBit is less than StartBit, then ASSERT().
840   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
841   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
842 
843   @param  Address   The PCI configuration register to write.
844   @param  StartBit  The ordinal of the least significant bit in the bit field.
845                     Range 0..15.
846   @param  EndBit    The ordinal of the most significant bit in the bit field.
847                     Range 0..15.
848   @param  AndData   The value to AND with the PCI configuration register.
849   @param  OrData    The value to OR with the result of the AND operation.
850 
851   @return The value written back to the PCI configuration register.
852 
853 **/
854 UINT16
855 EFIAPI
PciBitFieldAndThenOr16(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 AndData,IN UINT16 OrData)856 PciBitFieldAndThenOr16 (
857   IN      UINTN                     Address,
858   IN      UINTN                     StartBit,
859   IN      UINTN                     EndBit,
860   IN      UINT16                    AndData,
861   IN      UINT16                    OrData
862   )
863 {
864   return PciWrite16 (
865            Address,
866            BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)
867            );
868 }
869 
870 /**
871   Reads a 32-bit PCI configuration register.
872 
873   Reads and returns the 32-bit PCI configuration register specified by Address.
874   This function must guarantee that all PCI read and write operations are
875   serialized.
876 
877   If Address > 0x0FFFFFFF, then ASSERT().
878   If Address is not aligned on a 32-bit boundary, then ASSERT().
879 
880   @param  Address The address that encodes the PCI Bus, Device, Function and
881                   Register.
882 
883   @return The read value from the PCI configuration register.
884 
885 **/
886 UINT32
887 EFIAPI
PciRead32(IN UINTN Address)888 PciRead32 (
889   IN      UINTN                     Address
890   )
891 {
892   ASSERT_INVALID_PCI_ADDRESS (Address, 3);
893 
894   return PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint32);
895 }
896 
897 /**
898   Writes a 32-bit PCI configuration register.
899 
900   Writes the 32-bit PCI configuration register specified by Address with the
901   value specified by Value. Value is returned. This function must guarantee
902   that all PCI read and write operations are serialized.
903 
904   If Address > 0x0FFFFFFF, then ASSERT().
905   If Address is not aligned on a 32-bit boundary, then ASSERT().
906 
907   @param  Address The address that encodes the PCI Bus, Device, Function and
908                   Register.
909   @param  Value   The value to write.
910 
911   @return The value written to the PCI configuration register.
912 
913 **/
914 UINT32
915 EFIAPI
PciWrite32(IN UINTN Address,IN UINT32 Value)916 PciWrite32 (
917   IN      UINTN                     Address,
918   IN      UINT32                    Value
919   )
920 {
921   ASSERT_INVALID_PCI_ADDRESS (Address, 3);
922 
923   return PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint32, Value);
924 }
925 
926 /**
927   Performs a bitwise OR of a 32-bit PCI configuration register with
928   a 32-bit value.
929 
930   Reads the 32-bit PCI configuration register specified by Address, performs a
931   bitwise OR between the read result and the value specified by
932   OrData, and writes the result to the 32-bit PCI configuration register
933   specified by Address. The value written to the PCI configuration register is
934   returned. This function must guarantee that all PCI read and write operations
935   are serialized.
936 
937   If Address > 0x0FFFFFFF, then ASSERT().
938   If Address is not aligned on a 32-bit boundary, then ASSERT().
939 
940   @param  Address The address that encodes the PCI Bus, Device, Function and
941                   Register.
942   @param  OrData  The value to OR with the PCI configuration register.
943 
944   @return The value written back to the PCI configuration register.
945 
946 **/
947 UINT32
948 EFIAPI
PciOr32(IN UINTN Address,IN UINT32 OrData)949 PciOr32 (
950   IN      UINTN                     Address,
951   IN      UINT32                    OrData
952   )
953 {
954   return PciWrite32 (Address, PciRead32 (Address) | OrData);
955 }
956 
957 /**
958   Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
959   value.
960 
961   Reads the 32-bit PCI configuration register specified by Address, performs a
962   bitwise AND between the read result and the value specified by AndData, and
963   writes the result to the 32-bit PCI configuration register specified by
964   Address. The value written to the PCI configuration register is returned.
965   This function must guarantee that all PCI read and write operations are
966   serialized.
967 
968   If Address > 0x0FFFFFFF, then ASSERT().
969   If Address is not aligned on a 32-bit boundary, then ASSERT().
970 
971   @param  Address The address that encodes the PCI Bus, Device, Function and
972                   Register.
973   @param  AndData The value to AND with the PCI configuration register.
974 
975   @return The value written back to the PCI configuration register.
976 
977 **/
978 UINT32
979 EFIAPI
PciAnd32(IN UINTN Address,IN UINT32 AndData)980 PciAnd32 (
981   IN      UINTN                     Address,
982   IN      UINT32                    AndData
983   )
984 {
985   return PciWrite32 (Address, PciRead32 (Address) & AndData);
986 }
987 
988 /**
989   Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
990   value, followed a  bitwise OR with another 32-bit value.
991 
992   Reads the 32-bit PCI configuration register specified by Address, performs a
993   bitwise AND between the read result and the value specified by AndData,
994   performs a bitwise OR between the result of the AND operation and
995   the value specified by OrData, and writes the result to the 32-bit PCI
996   configuration register specified by Address. The value written to the PCI
997   configuration register is returned. This function must guarantee that all PCI
998   read and write operations are serialized.
999 
1000   If Address > 0x0FFFFFFF, then ASSERT().
1001   If Address is not aligned on a 32-bit boundary, then ASSERT().
1002 
1003   @param  Address The address that encodes the PCI Bus, Device, Function and
1004                   Register.
1005   @param  AndData The value to AND with the PCI configuration register.
1006   @param  OrData  The value to OR with the result of the AND operation.
1007 
1008   @return The value written back to the PCI configuration register.
1009 
1010 **/
1011 UINT32
1012 EFIAPI
PciAndThenOr32(IN UINTN Address,IN UINT32 AndData,IN UINT32 OrData)1013 PciAndThenOr32 (
1014   IN      UINTN                     Address,
1015   IN      UINT32                    AndData,
1016   IN      UINT32                    OrData
1017   )
1018 {
1019   return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);
1020 }
1021 
1022 /**
1023   Reads a bit field of a PCI configuration register.
1024 
1025   Reads the bit field in a 32-bit PCI configuration register. The bit field is
1026   specified by the StartBit and the EndBit. The value of the bit field is
1027   returned.
1028 
1029   If Address > 0x0FFFFFFF, then ASSERT().
1030   If Address is not aligned on a 32-bit boundary, then ASSERT().
1031   If StartBit is greater than 31, then ASSERT().
1032   If EndBit is greater than 31, then ASSERT().
1033   If EndBit is less than StartBit, then ASSERT().
1034 
1035   @param  Address   The PCI configuration register to read.
1036   @param  StartBit  The ordinal of the least significant bit in the bit field.
1037                     Range 0..31.
1038   @param  EndBit    The ordinal of the most significant bit in the bit field.
1039                     Range 0..31.
1040 
1041   @return The value of the bit field read from the PCI configuration register.
1042 
1043 **/
1044 UINT32
1045 EFIAPI
PciBitFieldRead32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit)1046 PciBitFieldRead32 (
1047   IN      UINTN                     Address,
1048   IN      UINTN                     StartBit,
1049   IN      UINTN                     EndBit
1050   )
1051 {
1052   return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);
1053 }
1054 
1055 /**
1056   Writes a bit field to a PCI configuration register.
1057 
1058   Writes Value to the bit field of the PCI configuration register. The bit
1059   field is specified by the StartBit and the EndBit. All other bits in the
1060   destination PCI configuration register are preserved. The new value of the
1061   32-bit register is returned.
1062 
1063   If Address > 0x0FFFFFFF, then ASSERT().
1064   If Address is not aligned on a 32-bit boundary, then ASSERT().
1065   If StartBit is greater than 31, then ASSERT().
1066   If EndBit is greater than 31, then ASSERT().
1067   If EndBit is less than StartBit, then ASSERT().
1068   If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1069 
1070   @param  Address   The PCI configuration register to write.
1071   @param  StartBit  The ordinal of the least significant bit in the bit field.
1072                     Range 0..31.
1073   @param  EndBit    The ordinal of the most significant bit in the bit field.
1074                     Range 0..31.
1075   @param  Value     The new value of the bit field.
1076 
1077   @return The value written back to the PCI configuration register.
1078 
1079 **/
1080 UINT32
1081 EFIAPI
PciBitFieldWrite32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 Value)1082 PciBitFieldWrite32 (
1083   IN      UINTN                     Address,
1084   IN      UINTN                     StartBit,
1085   IN      UINTN                     EndBit,
1086   IN      UINT32                    Value
1087   )
1088 {
1089   return PciWrite32 (
1090            Address,
1091            BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)
1092            );
1093 }
1094 
1095 /**
1096   Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1097   writes the result back to the bit field in the 32-bit port.
1098 
1099   Reads the 32-bit PCI configuration register specified by Address, performs a
1100   bitwise OR between the read result and the value specified by
1101   OrData, and writes the result to the 32-bit PCI configuration register
1102   specified by Address. The value written to the PCI configuration register is
1103   returned. This function must guarantee that all PCI read and write operations
1104   are serialized. Extra left bits in OrData 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 OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1112 
1113   @param  Address   The 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  OrData    The value to OR with the PCI configuration register.
1119 
1120   @return The value written back to the PCI configuration register.
1121 
1122 **/
1123 UINT32
1124 EFIAPI
PciBitFieldOr32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 OrData)1125 PciBitFieldOr32 (
1126   IN      UINTN                     Address,
1127   IN      UINTN                     StartBit,
1128   IN      UINTN                     EndBit,
1129   IN      UINT32                    OrData
1130   )
1131 {
1132   return PciWrite32 (
1133            Address,
1134            BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)
1135            );
1136 }
1137 
1138 /**
1139   Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1140   AND, and writes the result back to the bit field in the 32-bit register.
1141 
1142   Reads the 32-bit PCI configuration register specified by Address, performs a
1143   bitwise AND between the read result and the value specified by AndData, and
1144   writes the result to the 32-bit PCI configuration register specified by
1145   Address. The value written to the PCI configuration register is returned.
1146   This function must guarantee that all PCI read and write operations are
1147   serialized. Extra left bits in AndData are stripped.
1148 
1149   If Address > 0x0FFFFFFF, then ASSERT().
1150   If Address is not aligned on a 32-bit boundary, then ASSERT().
1151   If StartBit is greater than 31, then ASSERT().
1152   If EndBit is greater than 31, then ASSERT().
1153   If EndBit is less than StartBit, then ASSERT().
1154   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1155 
1156   @param  Address   The 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 
1163   @return The value written back to the PCI configuration register.
1164 
1165 **/
1166 UINT32
1167 EFIAPI
PciBitFieldAnd32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 AndData)1168 PciBitFieldAnd32 (
1169   IN      UINTN                     Address,
1170   IN      UINTN                     StartBit,
1171   IN      UINTN                     EndBit,
1172   IN      UINT32                    AndData
1173   )
1174 {
1175   return PciWrite32 (
1176            Address,
1177            BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)
1178            );
1179 }
1180 
1181 /**
1182   Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1183   bitwise OR, and writes the result back to the bit field in the
1184   32-bit port.
1185 
1186   Reads the 32-bit PCI configuration register specified by Address, performs a
1187   bitwise AND followed by a bitwise OR between the read result and
1188   the value specified by AndData, and writes the result to the 32-bit PCI
1189   configuration register specified by Address. The value written to the PCI
1190   configuration register is returned. This function must guarantee that all PCI
1191   read and write operations are serialized. Extra left bits in both AndData and
1192   OrData are stripped.
1193 
1194   If Address > 0x0FFFFFFF, then ASSERT().
1195   If Address is not aligned on a 32-bit boundary, then ASSERT().
1196   If StartBit is greater than 31, then ASSERT().
1197   If EndBit is greater than 31, then ASSERT().
1198   If EndBit is less than StartBit, then ASSERT().
1199   If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1200   If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1201 
1202   @param  Address   The PCI configuration register to write.
1203   @param  StartBit  The ordinal of the least significant bit in the bit field.
1204                     Range 0..31.
1205   @param  EndBit    The ordinal of the most significant bit in the bit field.
1206                     Range 0..31.
1207   @param  AndData   The value to AND with the PCI configuration register.
1208   @param  OrData    The value to OR with the result of the AND operation.
1209 
1210   @return The value written back to the PCI configuration register.
1211 
1212 **/
1213 UINT32
1214 EFIAPI
PciBitFieldAndThenOr32(IN UINTN Address,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 AndData,IN UINT32 OrData)1215 PciBitFieldAndThenOr32 (
1216   IN      UINTN                     Address,
1217   IN      UINTN                     StartBit,
1218   IN      UINTN                     EndBit,
1219   IN      UINT32                    AndData,
1220   IN      UINT32                    OrData
1221   )
1222 {
1223   return PciWrite32 (
1224            Address,
1225            BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)
1226            );
1227 }
1228 
1229 /**
1230   Reads a range of PCI configuration registers into a caller supplied buffer.
1231 
1232   Reads the range of PCI configuration registers specified by StartAddress and
1233   Size into the buffer specified by Buffer. This function only allows the PCI
1234   configuration registers from a single PCI function to be read. Size is
1235   returned. When possible 32-bit PCI configuration read cycles are used to read
1236   from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1237   and 16-bit PCI configuration read cycles may be used at the beginning and the
1238   end of the range.
1239 
1240   If StartAddress > 0x0FFFFFFF, then ASSERT().
1241   If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1242   If Size > 0 and Buffer is NULL, then ASSERT().
1243 
1244   @param  StartAddress  The starting address that encodes the PCI Bus, Device,
1245                         Function and Register.
1246   @param  Size          The size in bytes of the transfer.
1247   @param  Buffer        The pointer to a buffer receiving the data read.
1248 
1249   @return Size
1250 
1251 **/
1252 UINTN
1253 EFIAPI
PciReadBuffer(IN UINTN StartAddress,IN UINTN Size,OUT VOID * Buffer)1254 PciReadBuffer (
1255   IN      UINTN                     StartAddress,
1256   IN      UINTN                     Size,
1257   OUT     VOID                      *Buffer
1258   )
1259 {
1260   UINTN                             ReturnValue;
1261 
1262   ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);
1263   ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
1264 
1265   if (Size == 0) {
1266     return Size;
1267   }
1268 
1269   ASSERT (Buffer != NULL);
1270 
1271   //
1272   // Save Size for return
1273   //
1274   ReturnValue = Size;
1275 
1276   if ((StartAddress & BIT0) != 0) {
1277     //
1278     // Read a byte if StartAddress is byte aligned
1279     //
1280     *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);
1281     StartAddress += sizeof (UINT8);
1282     Size -= sizeof (UINT8);
1283     Buffer = (UINT8*)Buffer + 1;
1284   }
1285 
1286   if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
1287     //
1288     // Read a word if StartAddress is word aligned
1289     //
1290     WriteUnaligned16 (Buffer, PciRead16 (StartAddress));
1291     StartAddress += sizeof (UINT16);
1292     Size -= sizeof (UINT16);
1293     Buffer = (UINT16*)Buffer + 1;
1294   }
1295 
1296   while (Size >= sizeof (UINT32)) {
1297     //
1298     // Read as many double words as possible
1299     //
1300     WriteUnaligned32 (Buffer, PciRead32 (StartAddress));
1301     StartAddress += sizeof (UINT32);
1302     Size -= sizeof (UINT32);
1303     Buffer = (UINT32*)Buffer + 1;
1304   }
1305 
1306   if (Size >= sizeof (UINT16)) {
1307     //
1308     // Read the last remaining word if exist
1309     //
1310     WriteUnaligned16 (Buffer, PciRead16 (StartAddress));
1311     StartAddress += sizeof (UINT16);
1312     Size -= sizeof (UINT16);
1313     Buffer = (UINT16*)Buffer + 1;
1314   }
1315 
1316   if (Size >= sizeof (UINT8)) {
1317     //
1318     // Read the last remaining byte if exist
1319     //
1320     *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);
1321   }
1322 
1323   return ReturnValue;
1324 }
1325 
1326 /**
1327   Copies the data in a caller supplied buffer to a specified range of PCI
1328   configuration space.
1329 
1330   Writes the range of PCI configuration registers specified by StartAddress and
1331   Size from the buffer specified by Buffer. This function only allows the PCI
1332   configuration registers from a single PCI function to be written. Size is
1333   returned. When possible 32-bit PCI configuration write cycles are used to
1334   write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1335   8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1336   and the end of the range.
1337 
1338   If StartAddress > 0x0FFFFFFF, then ASSERT().
1339   If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1340   If Size > 0 and Buffer is NULL, then ASSERT().
1341 
1342   @param  StartAddress  The starting address that encodes the PCI Bus, Device,
1343                         Function and Register.
1344   @param  Size          The size in bytes of the transfer.
1345   @param  Buffer        The pointer to a buffer containing the data to write.
1346 
1347   @return Size written to StartAddress.
1348 
1349 **/
1350 UINTN
1351 EFIAPI
PciWriteBuffer(IN UINTN StartAddress,IN UINTN Size,IN VOID * Buffer)1352 PciWriteBuffer (
1353   IN      UINTN                     StartAddress,
1354   IN      UINTN                     Size,
1355   IN      VOID                      *Buffer
1356   )
1357 {
1358   UINTN                             ReturnValue;
1359 
1360   ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);
1361   ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
1362 
1363   if (Size == 0) {
1364     return 0;
1365   }
1366 
1367   ASSERT (Buffer != NULL);
1368 
1369   //
1370   // Save Size for return
1371   //
1372   ReturnValue = Size;
1373 
1374   if ((StartAddress & BIT0) != 0) {
1375     //
1376     // Write a byte if StartAddress is byte aligned
1377     //
1378     PciWrite8 (StartAddress, *(UINT8*)Buffer);
1379     StartAddress += sizeof (UINT8);
1380     Size -= sizeof (UINT8);
1381     Buffer = (UINT8*)Buffer + 1;
1382   }
1383 
1384   if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
1385     //
1386     // Write a word if StartAddress is word aligned
1387     //
1388     PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));
1389     StartAddress += sizeof (UINT16);
1390     Size -= sizeof (UINT16);
1391     Buffer = (UINT16*)Buffer + 1;
1392   }
1393 
1394   while (Size >= sizeof (UINT32)) {
1395     //
1396     // Write as many double words as possible
1397     //
1398     PciWrite32 (StartAddress, ReadUnaligned32 (Buffer));
1399     StartAddress += sizeof (UINT32);
1400     Size -= sizeof (UINT32);
1401     Buffer = (UINT32*)Buffer + 1;
1402   }
1403 
1404   if (Size >= sizeof (UINT16)) {
1405     //
1406     // Write the last remaining word if exist
1407     //
1408     PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));
1409     StartAddress += sizeof (UINT16);
1410     Size -= sizeof (UINT16);
1411     Buffer = (UINT16*)Buffer + 1;
1412   }
1413 
1414   if (Size >= sizeof (UINT8)) {
1415     //
1416     // Write the last remaining byte if exist
1417     //
1418     PciWrite8 (StartAddress, *(UINT8*)Buffer);
1419   }
1420 
1421   return ReturnValue;
1422 }
1423