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