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