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