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