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