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