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