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