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