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